2^12枚举修复哪些桥,不修复的桥没有花费,连接的边流量为1,要修复的桥则计算花费,边的流量为无穷,建立最大流模型来求解,增加一个源点S,和一个汇点T。S向每个有人的点,连一条容量为人数的边,图中普通的u->v的有向边,连一条u->v的流量为无穷的边,对于u->v的隧道,可以连接u->v的流量无穷的边,和u->T的流量为隧道人数上限的边,求解最大流即可。
#include<stdio.h>
#include<string.h>
#define N 1105
#define oo 2000000000
int head[N],idx;
struct edge{
int u,v,nt,cap;
edge(){}
edge(int u,int v,int nt,int cap):u(u),v(v),nt(nt),cap(cap){}
}e[N*N];
int level[N],cur[N],ps[N];
int s,t;
int x[N],y[N],z[N],p[N],pv[N];
void AddEdge(int u,int v,int c){
e[idx]=edge(u,v,head[u],c);head[u]=idx++;
e[idx]=edge(v,u,head[v],0);head[v]=idx++;
}
int dinic(){
int i,j,k,top,f,r;
int tr,res=0;
while(1)
{
memset(level,-1,sizeof(level));
for(f=level[ps[0]=s]=0,r=1;f!=r;)
for(i=ps[f++],j=head[i];j!=-1;j=e[j].nt)
{
if(e[j].cap>0&&-1==level[k=e[j].v])
{
level[k]=level[i]+1;
ps[r++]=k;
if(k==t) {f=r;break;}
}
}
if(-1==level[t]) break;
memcpy(cur,head,sizeof(head));
for(i=s,top=0;;)
{
if(i==t)
{
tr=oo;
for(k=0;k<top;k++)
if(e[ps[k]].cap<tr) tr=e[ps[f=k]].cap;
for(k=0;k<top;k++)
e[ps[k]].cap-=tr,e[ps[k]^1].cap+=tr;
res+=tr;
i=e[ps[top=f]].u;
}
for(j=cur[i];j!=-1;j=cur[i]=e[cur[i]].nt)
if(e[j].cap>0&&level[i]+1==level[e[j].v]) break;
if(cur[i]!=-1){
ps[top++]=cur[i];
i=e[cur[i]].v;
}
else
{
if(!top) break;
level[i]=-1;
i=e[ps[--top]].u;
}
}
}
return res;
}
int n,m;
int main(){
while(scanf("%d%d",&n,&m)!=EOF)
{
int cnt=0;
for(int i=1;i<=n;i++) scanf("%d",pv+i);
bool flag=0;
for(int i=0;i<m;i++){
scanf("%d%d%d%d",x+i,y+i,z+i,p+i);
if(p[i]<0) flag=1;
if(p[i]>0) cnt++;
}
if(!flag)
{
puts("Poor Heaven Empire");
continue;
}
int maxnum=0,minsum=0;
s=0,t=n+1;
for(int w=0;w<(1<<cnt);w++){
memset(head,-1,sizeof(head));
idx=0;
int j=0,i;
int num,sum=0;
for(int i=1;i<=n;i++) AddEdge(s,i,pv[i]);
for(int i=0;i<m;i++)
{
if(p[i]==0) {AddEdge(x[i],y[i],oo);}
if(p[i]<0){AddEdge(x[i],t,z[i]);AddEdge(x[i],y[i],oo);}
if(p[i]>0)
{
if(w&(1<<j))
{
AddEdge(x[i],y[i],oo);
sum+=z[i];
}
else AddEdge(x[i],y[i],1);
j++;
}
}
num=dinic();
if(num>maxnum||(num==maxnum&&sum<minsum)) maxnum=num,minsum=sum;
}
if(maxnum==0) puts("Poor Heaven Empire");
else
printf("%d %d\n",maxnum,minsum);
}
}
/*
*/
本文通过最大流模型解决城市桥梁修复问题,利用源点S和汇点T建立模型,通过增加流量来确定最优修复方案,确保城市交通畅通。

1326

被折叠的 条评论
为什么被折叠?



