Author: | Andrew Stankevich |
Resource: | Petrozavodsk Winter Trainings 2003 |
Date: | 2003-02-06 |
#include<cstdio>
#include<cstring>
struct TT
{
int a,b,l,r;
} pipe[210*210];
int map[210][210];
int s,t;
int n,m,dist[210],gap[210];
int min(int a,int b)
{
if(a>b) return b;
return a;
}
int find_path(int p,int limit = 0x3f3f3f3f)
{
if(p==t) return limit;
for(int i=0;i<n;++i)
{
if(dist[p]==dist[i]+1&&map[p][i]>0)
{
int t=find_path(i,min(limit,map[p][i]));
if(t<0) return t;
if(t>0)
{
map[p][i]-=t;
map[i][p]+=t;
return t;
}
}
}
int label=n;
for(int i=0;i<n;++i)
if(map[p][i]>0) label=min(label,dist[i]+1);
if (--gap[dist[p]]==0||dist[0]>=n) return -1;
++gap[dist[p]=label];
return 0;
}
int Isap()
{
gap[s]=n;
int maxflow=0,t=0;
while((t=find_path(s))>=0) maxflow+=t;
return maxflow;
}
int main()
{
while(scanf("%d%d",&n,&m)!=EOF)
{
memset(map,0,sizeof(map));
memset(dist,0,sizeof(dist));
memset(gap,0,sizeof(gap));
s=0;
t=n+1;
for(int i=1; i<=m; i++)
{
scanf("%d%d%d%d",&pipe[i].a,&pipe[i].b,&pipe[i].l,&pipe[i].r);
map[pipe[i].a][pipe[i].b]=pipe[i].r-pipe[i].l;//已经知道L一定比R大
map[s][pipe[i].b]+=pipe[i].l;
map[pipe[i].a][t]+=pipe[i].l;
}
n=n+2;
bool flag=true;
int k=Isap();
for(int i=1;i<=m;i++)
if(map[s][pipe[i].b]!=0 || map[pipe[i].a][t]!=0 )
{
flag=false;
break;
}
if(!flag) printf("NO/n");
else
{
printf("YES/n");
for(int i=1;i<=m;i++)
printf("%d/n",pipe[i].l+map[pipe[i].b][pipe[i].a]);
}
}
return 0;
}
邻接表形式
#include<cstdio>
#include<cstring>
const int N=210;
const int M=510*510;
const int inf=0x7fffffff;
int head[N];
int map[N][N];
int num[N*N],ru[N*N],chu[N*N];
struct TTT
{
int a,b,l,r;
}pipe[210*210];
struct Edge
{
int v,next,w;
} edge[M];
int cnt,n,s,t;
void addedge(int u,int v,int w)
{
edge[cnt].v=v;
edge[cnt].w=w;
edge[cnt].next=head[u];
head[u]=cnt++;
edge[cnt].v=u;
edge[cnt].w=0;
edge[cnt].next=head[v];
head[v]=cnt++;
}
int sap()
{
int pre[N],cur[N],dis[N],gap[N];
int flow=0,aug=inf,u;
bool flag;
for(int i=0; i<n; i++)
{
cur[i]=head[i];
gap[i]=dis[i]=0;
}
gap[s]=n;
u=pre[s]=s;
while(dis[s]<n)
{
flag=0;
for(int &j=cur[u]; j!=-1; j=edge[j].next)
{
int v=edge[j].v;
if(edge[j].w>0&&dis[u]==dis[v]+1)
{
flag=1;
if(edge[j].w<aug) aug=edge[j].w;
pre[v]=u;
u=v;
if(u==t)
{
flow+=aug;
while(u!=s)
{
u=pre[u];
edge[cur[u]].w-=aug;
edge[cur[u]^1].w+=aug;
}
aug=inf;
}
break;
}
}
if(flag) continue;
int mindis=n;
for(int j=head[u]; j!=-1; j=edge[j].next)
{
int v=edge[j].v;
if(edge[j].w>0&&dis[v]<mindis)
{
mindis=dis[v];
cur[u]=j;
}
}
if((--gap[dis[u]])==0)
break;
gap[dis[u]=mindis+1]++;
u=pre[u];
}
return flow;
}
int main()
{
int m;
while(scanf("%d%d",&n,&m)!=EOF)
{
s=0;
t=n+1;
cnt=0;
memset(head,-1,sizeof(head));
for(int i=1;i<=m;i++)
{
scanf("%d%d%d%d",&pipe[i].a,&pipe[i].b,&pipe[i].l,&pipe[i].r);
num[i]=cnt+1;
addedge(pipe[i].a,pipe[i].b,pipe[i].r-pipe[i].l);
ru[i]=cnt;
addedge(s,pipe[i].b,pipe[i].l);
chu[i]=cnt;
addedge(pipe[i].a,t,pipe[i].l);
}
n=n+2;
int t=sap();
bool flag=false;
for(int i=1;i<=m;i++)
if(edge[ru[i]].w!=0||edge[chu[i]].w!=0)
{
flag=true;
break;
}
if(flag) printf("NO/n");
else
{
printf("YES/n");
for(int i=1;i<=m;i++)
printf("%d/n",pipe[i].l+edge[num[i]].w);
}
}
return 0;
}