比赛 |
HAOI2009 模拟试题1 |
评测结果 |
PPPPPPPPPP |
题目名称 |
上学路线 |
最终得分 |
40 |
用户昵称 |
BYVoid |
运行时间 |
0.000 s |
代码语言 |
C++ |
内存使用 |
0.00 MiB |
提交时间 |
2009-04-21 10:22:03 |
显示代码纯文本
/*
* Problem: HAOI2008 parterre
* Author: Guo Jiabao
* Time: 2009.4.20
* State: Unsolved
* Memo: 备注
*/
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <cstring>
const int MAXN=501,MAXM=124751*4,INF=0x7FFFFFF;
using namespace std;
struct edge
{
edge *next,*op;
int t,d,c,id;
}*Vr[MAXN],*V[MAXN],ES[MAXM],*EP[MAXM],*P[MAXN],*Stae[MAXN];
int N,M,EC,S,T,Ecnt;
int sp[MAXN],Cost[MAXM],Anse[MAXM];
bool vis[MAXN];
int Lv[MAXN],Q[MAXN],Stap[MAXN],Stop;
bool dinic_bfs()
{
int i,j,head=0,tail=-1;
memset(Lv,-1,sizeof(Lv));
Q[++tail]=S;
Lv[S]=0;
while (head<=tail)
{
i=Q[head++];
for (edge *e=V[i];e;e=e->next)
{
if (Lv[j=e->t]==-1 && e->c)
{
Lv[j]=Lv[i]+1;
Q[++tail]=j;
if (j==T)
return true;
}
}
}
return false;
}
int dinic_augment()
{
int i,j,k,delta,Flow=0;
for (i=S;i<=T;i++)
P[i]=V[i];
Stap[Stop=1]=S;
while (Stop)
{
i=Stap[Stop];
if (i!=T)
{
for (;P[i];P[i]=P[i]->next)
if (P[i]->c && Lv[i]+1==Lv[j=P[i]->t])
break;
if (P[i])
{
Stap[++Stop]=j;
Stae[Stop]=P[i];
}
else
{
Stop--;
Lv[i]=-1;
}
}
else
{
delta=INF;
for (j=Stop;j>=2;j--)
if (Stae[j]->c < delta)
delta=Stae[j]->c;
Flow+=delta;
for (j=Stop;j>=2;j--)
{
Stae[j]->c-=delta;
Stae[j]->op->c+=delta;
if (Stae[j]->c==0)
k=j-1;
}
Stop=k;
}
}
return Flow;
}
int dinic()
{
int Flow=0;
while (dinic_bfs())
Flow += dinic_augment();
return Flow;
}
inline void addedge1(int a,int b,int d,int c,int id)
{
ES[++EC].next=Vr[a];
Vr[a]=ES+EC; Vr[a]->t=b; Vr[a]->c=c; Vr[a]->d=d;
ES[++EC].next=Vr[b];
Vr[b]=ES+EC; Vr[b]->t=a; Vr[b]->c=c; Vr[b]->d=d;
Vr[a]->id=Vr[b]->id=id;
Vr[a]->op=Vr[b]; Vr[b]->op=Vr[a];
}
inline void addedge2(int a,int b,int c,int id)
{
ES[++EC].next=V[a];
V[a]=ES+EC; V[a]->t=b; V[a]->c=c;
V[a]->id=id;
ES[++EC].next=V[b];
V[b]=ES+EC; V[b]->t=a; V[b]->c=0;
V[a]->op=V[b]; V[b]->op=V[a];
}
void init()
{
int i,a,b,d,c;
freopen("routez.in","r",stdin);
freopen("routez.out","w",stdout);
scanf("%d%d",&N,&M);
EC=0;
for (i=1;i<=M;i++)
{
scanf("%d%d%d%d",&a,&b,&d,&c);
addedge1(a,b,d,c,i);
}
}
void dijkstra()
{
int i,j,Mini;
for (i=1;i<=N;i++)
sp[i]=INF;
sp[i=1]=0;
for (;i;)
{
vis[i]=true;
for (edge *e=Vr[i];e;e=e->next)
{
j=e->t;
if (sp[i] + e->d < sp[j])
sp[j] = sp[i]+ e->d;
}
i=0;Mini=INF;
for (j=1;j<=N;j++)
if (!vis[j] && sp[j]<Mini)
{
Mini=sp[j];
i=j;
}
}
}
void makenetwork(int i)
{
vis[i]=true;
for (edge *e=Vr[i];e;e=e->next)
{
int j=e->t;
if (!vis[j] && sp[j] + e->d == sp[i])
{
addedge2(j,i,e->c,e->id);
if (j!=S)
makenetwork(j);
}
}
}
inline int cmp(const void *a,const void *b)
{
edge *A=(*(edge **)a),*B=(*(edge **)b);
return A->id - B->id;
}
void network()
{
int p=EC+1;
memset(vis,0,sizeof(vis));
S=1,T=N;
makenetwork(T);
Ecnt=0;
for (int i=p;i<=EC;i++)
if (ES[i].c)
EP[++Ecnt]=ES+i;
qsort(EP+1,Ecnt,sizeof(EP[0]),cmp);
}
void solve()
{
int Ans1,Ans2,Ans3,i,j,Flow,CFlow;
dijkstra();
Ans1=sp[N];
network();
for (j=1;j<=Ecnt;j++)
Cost[j]=EP[j]->c;
Ans3=CFlow=dinic();
Ans2=0;
for (i=1;i<=Ecnt && CFlow;i++)
{
for (j=1;j<=Ecnt;j++)
EP[j]->c=Cost[j];
EP[i]->c=0;
Flow=dinic();
if (CFlow - Flow == Cost[i])
{
Anse[++Ans2]=EP[i]->id;
CFlow=Flow;
Cost[i]=0;
}
}
printf("%d\n%d %d",Ans1,Ans2,Ans3);
for (i=1;i<=Ans2;i++)
printf(" %d",Anse[i]);
printf("\n");
}
int main()
{
init();
solve();
return 0;
}