记录编号 |
9834 |
评测结果 |
AAAAAAAAAA |
题目名称 |
[AHOI2008] 上学路线 |
最终得分 |
100 |
用户昵称 |
BYVoid |
是否通过 |
通过 |
代码语言 |
C++ |
运行时间 |
0.574 s |
提交时间 |
2009-04-21 17:40:27 |
内存使用 |
17.41 MiB |
显示代码纯文本
/*
* Problem: HAOI2008 parterre
* Author: Guo Jiabao
* Time: 2009.4.20 10:23
* State: Solved
* 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 s,t,d,c,id;
}*Vr[MAXN],*V[MAXN],ES[MAXM],*P[MAXN],*Stae[MAXN];
int N,M,EC,S,T,Ecnt;
int sp[2][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]->op=Vr[b]; Vr[b]->op=Vr[a];
Vr[a]->s=a; Vr[b]->s=b;
Vr[a]->id=Vr[b]->id=id;
}
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;
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];
V[a]->id=V[b]->id=id;
}
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 S,int *sp)
{
int i,j,Mini;
memset(vis,0,sizeof(vis));
for (i=1;i<=N;i++)
sp[i]=INF;
sp[i=S]=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 network()
{
int i,a,b,p=EC;
S=1,T=N;
Ecnt=0;
for (i=1;i<=p;i++)
{
a=ES[i].s,b=ES[i].t;
if (sp[0][a] + ES[i].d + sp[1][b] == sp[0][N])
addedge2(a,b,ES[i].c,ES[i].id);
}
}
int getcut()
{
int i,j,C=0;
dinic_bfs();
for (i=1;i<=N;i++)
{
for (edge *e=V[i];e;e=e->next)
{
j=e->t;
if (Lv[i]!=-1 && Lv[j]==-1)
Anse[++C]=e->id;
}
}
return C;
}
void solve()
{
int Ans1,Ans2,Ans3;
dijkstra(1,sp[0]);
dijkstra(N,sp[1]);
Ans1=sp[0][N];
network();
Ans3=dinic();
Ans2=getcut();
printf("%d\n%d %d\n",Ans1,Ans2,Ans3);
for (int i=1;i<=Ans2;i++)
printf("%d\n",Anse[i]);
}
int main()
{
init();
solve();
return 0;
}