记录编号 153225 评测结果 AAAAAAAAAA
题目名称 [ZJOI 2010] 网络扩容 最终得分 100
用户昵称 Gravatar水中音 是否通过 通过
代码语言 C++ 运行时间 0.019 s
提交时间 2015-03-17 15:02:32 内存使用 0.77 MiB
显示代码纯文本
#include<iostream>
#include<cstdio>
using namespace std;
#define INF 1e9
int i,p,n,m,k,zj1,zj2,zj3,zj4,ST,SD,ans;
int zhi[10010]={0},sj=1;
int to[20010]={0},fr[20010]={0},ne[20010]={0},r[20010]={0},w[20010]={0},head[1010]={0};
inline void addedge(int u,int v,int z)
{
	to[++sj]=v,fr[sj]=u,ne[sj]=head[u],head[u]=sj,r[sj]=z;
	to[++sj]=u,fr[sj]=v,ne[sj]=head[v],head[v]=sj,r[sj]=0;
}
 
int que[1010]={0},qhead=1,qtail=0;bool flag[1010]={0};
inline int GET()
{int x=que[qhead];flag[x]=0,que[0]--;if(++qhead==1010)qhead=1;return x;}
inline void PUSH(int x)
{que[0]++,flag[x]=1;if(++qtail==1010)qtail=1;que[qtail]=x;}
 
int lv[1010]={0},cnt[1010]={0};
void init()
{
	scanf("%d%d%d",&n,&m,&k);
	while(m--)
	{
		scanf("%d%d%d%d",&zj1,&zj2,&zj3,&zj4);
		addedge(zj1,zj2,zj3);zhi[sj-1]=zj4;zhi[sj]=-zj4;
	}
	ST=1,SD=n;PUSH(SD);
	while(que[0])
	for(zj1=GET(),i=head[zj1];i;i=ne[i])
	if(!r[i]&&!lv[to[i]])
	cnt[lv[to[i]]=lv[zj1]+1]++,PUSH(to[i]);
	cnt[lv[SD]]--,cnt[lv[SD]=0]=SD;
}
int pre[1010],cur[1010]={0};
void isap()
{
	ans=0;
	for(i=1;i<=SD;i++)cur[i]=head[i];
	int U=ST;pre[ST]=ST,zj1=INF;bool FLAG;
	while(lv[ST]<SD)
	{
		for(FLAG=0,i=cur[U];i;i=ne[i])
		{
			if(r[i]&&lv[to[i]]==lv[U]-1)
			{
				FLAG=1,pre[to[i]]=U,U=to[i];
				if(r[i]<zj1)zj1=r[i];
				if(U==SD)
				{
					while(U!=ST)
					U=pre[U],r[cur[U]]-=zj1,r[cur[U]^1]+=zj1;
					ans+=zj1,zj1=INF;
				}
				break;
			}
			cur[U]=ne[i];
		}
		if(FLAG)continue;
		if(!(--cnt[lv[U]]))break;
		for(zj2=SD+1,i=head[U];i;i=ne[i])
		if(r[i]&&zj2>lv[to[i]])zj2=lv[to[i]],cur[U]=i;
		cnt[lv[U]=zj2+1]++,U=pre[U];
	}
	printf("%d ",ans);
}
 
void Make()
{
	ans=0,zj1=sj,ST=n+1;
	for(i=2;i<=zj1;i+=2)
	{
		addedge(fr[i],to[i],k);
		w[sj-1]=zhi[i];w[sj]=zhi[i+1];
	}
	addedge(ST,1,k);
}
int dis[1010]={0},pres[1010]={0};
inline bool spfa()
{
	for(i=1;i<=SD;i++)dis[i]=INF;
	dis[ST]=0;PUSH(ST);
	while(que[0])
	{
		zj1=GET();
		for(i=head[zj1];i;i=ne[i])
		if(r[i]&&(dis[to[i]]>(zj2=dis[zj1]+w[i])))
		{
			dis[to[i]]=zj2,pre[to[i]]=zj1,pres[to[i]]=i;
			if(!flag[to[i]])PUSH(to[i]);
		}
	}
	if(dis[SD]==INF)return 0;
	return 1;
}
 
void work()
{
	for(zj2=INF,zj1=SD;zj1!=ST;zj1=pre[zj1])
	if(r[pres[zj1]]<zj2)zj2=r[pres[zj1]];
	for(zj1=SD;zj1!=ST;zj1=pre[zj1])
	r[pres[zj1]]-=zj2,r[pres[zj1]^1]+=zj2;
	ans+=dis[SD]*zj2;
}
 
int main()
{
	freopen("networkzj2010.in","r",stdin);
	freopen("networkzj2010.out","w",stdout);
	init();
	isap();
	Make();
	while(spfa())work();
	printf("%d\n",ans);
	return 0;
}