Seikimatsu Occult Tonneru(网络流,状态数(建不建边)不多时,可考虑直接进行枚举
http://acm.hdu.edu.cn/showproblem.php?pid=4309
总结:边可存东西时,可新建一个点x连接u、v,x再连向汇点;
#include<iostream> #include<cstring> #include<cstdio> #include<algorithm> #include<queue> using namespace std; typedef long long ll; #define pb push_back const ll INF=1e18; const int inf=0x3f3f3f3f; const int M=1e5+5; const int N=1e5+5; int a[M],head[M],cur[M],deep[M],s,t,tot,firnum,secnum,thnum; struct node{ int v,w,nextt; }e[N]; struct Node{ int u,v,w,cost; }fir[M],sec[M],th[M]; void addedge(int u,int v,int w){ e[tot].v=v; e[tot].w=w; e[tot].nextt=head[u]; head[u]=tot++; e[tot].v=u; e[tot].w=0; e[tot].nextt=head[v]; head[v]=tot++; } bool bfs(){ for(int i=0;i<=t;i++) deep[i]=0; queue<int>que; que.push(s); deep[s]=1; while(!que.empty()){ int u=que.front(); que.pop(); for(int i=head[u];~i;i=e[i].nextt){ int v=e[i].v; if(e[i].w>0&&deep[v]==0){ deep[v]=deep[u]+1; if(v==t) return true; que.push(v); } } } return deep[t]==0?false:true; } int dfs(int u,int fl){ if(u==t) return fl; int x,res=0; for(int i=cur[u];~i;i=e[i].nextt){ int v=e[i].v; if(e[i].w>0&&deep[v]==deep[u]+1){ x=dfs(v,min(fl-res,e[i].w)); res+=x; e[i].w-=x; e[i^1].w+=x; if(e[i].w) cur[u]=1; if(res==fl) return fl; } } if(res==0) deep[u]=0; return res; } int dinic(){ int res=0; while(bfs()){ for(int i=0;i<=t;i++) cur[i]=head[i]; res+=dfs(s,inf); } return res; } int n,ans,ansmin,mincost; void init(){ memset(head,-1,sizeof(head)); tot=0; mincost=0; } void solve(int now){ init(); for(int i=1;i<=n;i++) addedge(s,i,a[i]); for(int i=0;i<firnum;i++){ addedge(fir[i].u,n+1+i,inf); addedge(n+1+i,fir[i].v,inf); addedge(n+1+i,t,fir[i].w); } for(int i=0;i<secnum;i++){ addedge(sec[i].u,sec[i].v,inf); } for(int i=0;i<thnum;i++){ if(now & (1<<i) ){ addedge(th[i].u,th[i].v,inf); mincost+=th[i].cost; } else addedge(th[i].u,th[i].v,1); } int nowans=dinic(); if(nowans > ans){ ans = nowans; ansmin = mincost; }else if(nowans == ans){ ansmin=min(ansmin,mincost); } } int main(){ int m; while(scanf("%d%d",&n,&m)!=EOF){ ans=0; ansmin=inf; for(int i=1;i<=n;i++){ scanf("%d",&a[i]); } firnum=secnum=thnum=0; s=0; t=n+1; for(int u,v,w,p,i=1;i<=m;i++){ scanf("%d%d%d%d",&u,&v,&w,&p); if(p<0){ fir[firnum].u=u; fir[firnum].v=v; fir[firnum].w=w; firnum++; t++; //addedge(v,t,inf,0); } else if(p==0){ sec[secnum].u=u; sec[secnum].v=v; secnum++; } else{ th[thnum].u=u; th[thnum].v=v; th[thnum].cost=w; thnum++; } } //cout<<firnum<<":"<<secnum<<":"<<thnum<<endl; for(int i=0;i<=(1<<thnum)-1;i++) solve(i); if(ans==0) puts("Poor Heaven Empire"); else printf("%d %d\n",ans,ansmin); //puts(""); } return 0; }