您的位置:首页 > 其它

Soldier and Traveling

2016-09-22 22:07 435 查看

B.SoldierandTraveling

TimeLimit:1000ms
MemoryLimit:262144KB
64-bitintegerIOformat:%I64dJavaclassname:(Any)

SubmitStatus

Inthecountrytherearencitiesandmbidirectionalroadsbetweenthem.Eachcityhasanarmy.Armyofthei-thcityconsistsofaisoldiers.Nowsoldiersroam.Afterroamingeachsoldierhastoeitherstayinhiscityortogototheoneofneighboringcitiesbyatmovingalongatmostoneroad.

Checkifisitpossiblethatafterroamingtherewillbeexactlybisoldiersinthei-thcity.

Input

Firstlineofinputconsistsoftwointegersnandm(1 ≤ n ≤ 100,0 ≤ m ≤ 200).

Nextlinecontainsnintegersa1, a2, ..., an(0 ≤ ai ≤ 100).

Nextlinecontainsnintegersb1, b2, ..., bn(0 ≤ bi ≤ 100).

Thenmlinesfollow,eachofthemconsistsoftwointegerspandq(1 ≤ p, q ≤ n,p ≠ q)denotingthatthereisanundirectedroadbetweencitiespandq.

Itisguaranteedthatthereisatmostoneroadbetweeneachpairofcities.

Output

Iftheconditionscannotbemetoutputsingleword"NO".

Otherwiseoutputword"YES"andthennlines,eachofthemconsistingofnintegers.Numberinthei-thlineinthej-thcolumnshoulddenotehowmanysoldiersshouldroadfromcityitocityj(ifi ≠ j)orhowmanysoldiersshouldstayincityi(ifi = j).

Ifthereareseveralpossibleanswersyoumayoutputanyofthem.

SampleInput

Input
44
1263
3531
12
23
34
42


Output
YES
1000
2000
0510
0021


Input
20
12
21


Output
NO
思路:最大流;
首先判断变前和变后的和是否相等,如果不等则直接输出NO,否则,转换为最大流求解,原点和原来的点连边权值为原来的人口,然后每个新的状态和汇点连边,权值为后来的人口,然后
按给的边连边,权值为原来的人口,然后跑最大流,判断最大流量是否为sum。最后的矩阵由反边得来,表示从上个点有人口转移而来,反边的值就是转移人口。


#include<stdio.h>
#include<algorithm>
#include<iostream>
#include<stdlib.h>
#include<queue>
#include<string.h>
#include<map>
#include<vector>
usingnamespacestd;
typedeflonglongLL;
typedefstructpp
{
intto;
intcap;
intrev;
}aa;
vector<pp>vec[205];
intlevel[205];
intiter[205];
intans[105];
intbns[105];
voidadd(intfrom,intto,intcap);
voidbfs(ints);
intdfs(ints,intt,intf);
intmax_flow(ints,intt);
constintN=1e9;
intma[200][200];
intmain(void)
{
intn,m;
scanf("%d%d",&n,&m);
inti,j;
intsum1=0;
intsum2=0;
for(i=1;i<=n;i++)
{
scanf("%d",&ans[i]);
sum1+=ans[i];
}
for(i=1;i<=n;i++)
{
scanf("%d",&bns[i]);
sum2+=bns[i];
}
if(sum1!=sum2)
printf("NO\n");
else
{
for(i=1;i<=n;i++)
{
add(0,i,ans[i]);
add(i+n,2*n+1,bns[i]);
add(i,i+n,ans[i]);
}
while(m--)
{
intx,y;
scanf("%d%d",&x,&y);
add(x,y+n,ans[x]);
add(y,x+n,ans[y]);
}
intask=max_flow(0,2*n+1);
if(ask!=sum1)
printf("NO\n");
else
{
for(i=1;i<=n;i++)
{
intx=i+n;
for(j=0;j<vec[x].size();j++)
{
aano=vec[x][j];
ma[no.to][i]=no.cap;
}
}printf("YES\n");
for(i=1;i<=n;i++)
{
for(j=1;j<=n;j++)
{
if(j==1)
printf("%d",ma[i][j]);
elseprintf("%d",ma[i][j]);
}
printf("\n");
}
}
}return0;
}
voidadd(intfrom,intto,intcap)
{
ppnn;
nn.to=to;
nn.cap=cap;
nn.rev=vec[to].size();
vec[from].push_back(nn);
nn.to=from;
nn.cap=0;
nn.rev=vec[from].size()-1;
vec[to].push_back(nn);
}
voidbfs(ints)
{
queue<int>que;
memset(level,-1,sizeof(level));
level[s]=0;
que.push(s);
while(!que.empty())
{
intv=que.front();
que.pop();
inti;
for(i=0;i<vec[v].size();i++)
{
ppe=vec[v][i];
if(level[e.to]==-1&&e.cap>0)
{
level[e.to]=level[v]+1;
que.push(e.to);
}
}
}
}
intdfs(ints,intt,intf)
{
if(s==t)
returnf;
for(int&i=iter[s];i<vec[s].size();i++)
{
pp&e=vec[s][i];
if(level[e.to]>level[s]&&e.cap>0)
{
intr=dfs(e.to,t,min(e.cap,f));
if(r>0)
{
e.cap-=r;
vec[e.to][e.rev].cap+=r;
returnr;
}
}
}
return0;
}
intmax_flow(ints,intt)
{
intflow=0;
for(;;)
{
bfs(s);
if(level[t]<0)returnflow;
memset(iter,0,sizeof(iter));
intf;
while((f=dfs(s,t,N))>0)
{
flow+=f;
}
}
}



                                            
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: