比赛 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;
}