比赛 |
HAOI2009 模拟试题1 |
评测结果 |
AAAAAAAAAA |
题目名称 |
上学路线 |
最终得分 |
100 |
用户昵称 |
Pom |
运行时间 |
0.000 s |
代码语言 |
C++ |
内存使用 |
0.00 MiB |
提交时间 |
2011-03-25 19:18:41 |
显示代码纯文本
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
using namespace std;
const int MAXN=1000;
const int oo=1000000000;
struct edge
{
int t,f,num,c,fr;
bool b;
edge *p,*op;
}e[MAXN*MAXN],*v[MAXN],E[MAXN*MAXN],*V[MAXN],*path[MAXN][MAXN];
int i,j,k,n,m,lab[MAXN][MAXN],s[MAXN],ls=-1;
int d[MAXN],vd[MAXN],ans,es=-1,ff[MAXN*MAXN],MIN,t,x,y,da[MAXN*MAXN],c,ds;
bool used[MAXN],ad[MAXN][MAXN];
inline void addedge2(int i,int j,int c,int f,int num)
{
E[++ls].t=j; E[ls].p=V[i]; E[ls].fr=i; E[ls].c=c; E[ls].f=f; E[ls].num=num; V[i]=E+ls;
}
void init()
{
freopen("routez.in","r",stdin);
freopen("routez.out","w",stdout);
scanf("%d%d",&n,&m);
for (i=1;i<=m;i++)
{
scanf("%d%d%d%d",&x,&y,&c,&ff[i]);
addedge2(x,y,c,ff[i],i);
addedge2(y,x,c,ff[i],i);
}
memset(v,0,sizeof(v));
}
void dij()
{
for (i=1;i<=n;i++)
d[i]=oo;
memset(used,false,sizeof(used));
d[1]=0;
for (x=2;x<=n;x++)
{
MIN=oo;
for (i=1;i<=n;i++)
if (!used[i] && d[i]<MIN)
{
MIN=d[i];
t=i;
}
used[t]=true;
for (edge *X=V[t];X;X=X->p)
{
if (!used[X->t])
{
if (d[X->t]==X->c+d[t])
{
path[X->t][++s[X->t]]=X;
}
if (d[X->t]>X->c+d[t])
{
s[X->t]=1;
path[X->t][1]=X;
d[X->t]=X->c+d[t];
}
}
}
}
cout<<d[n]<<endl;
}
inline void addedge(int i,int j,int f,int num)
{
e[++es].t=j; e[es].p=v[i]; v[i]=e+es; e[es].f=f; e[es].num=num; e[es].b=true;
e[++es].t=i; e[es].p=v[j]; v[j]=e+es; e[es].f=0; e[es].num=num; e[es].b=false;
v[i]->op=v[j];
v[j]->op=v[i];
}
void df(int u)
{
int i;
if (u==1 || used[u]) return;
used[u]=true;
for (i=1;i<=s[u];i++)
{
edge *x=path[u][i];
addedge(x->fr,x->t,x->f,x->num);
df(x->fr);
}
}
int dfs(int u,int flow)
{
int re=0,tmp;
if (u==n) return flow;
for (edge *x=v[u];x;x=x->p)
if (d[u]==d[x->t]+1 && x->f)
{
tmp=dfs(x->t,min(flow-re,x->f));
x->f-=tmp;
x->op->f+=tmp;
re+=tmp;
if (re==flow) return re;
}
vd[d[u]]--;
if (!vd[d[u]]) d[1]=n;
vd[++d[u]]++;
return re;
}
void dd(int u)
{
if (used[u]) return;
used[u]=true;
for (edge *x=v[u];x;x=x->p)
if (x->b && !x->f) da[++ds]=x->num;
else
if (x->b)
dd(x->t);
}
void solve()
{
dij();
memset(used,false,sizeof(used));
memset(d,0,sizeof(d));
df(n);
vd[0]=n;
while (d[1]<n) ans+=dfs(1,oo);
memset(used,false,sizeof(used));
dd(1);
printf("%d %d\n",ds,ans);
for (i=1;i<=ds;i++)
cout<<da[i]<<endl;
}
int main()
{
init();
solve();
return 0;
}