zoj 2429 Destroying The Graph 最小点权覆盖
#include <cstdio> #include <string.h> #include <vector> using namespace std; #define Max 230 #define INF 100000000 int flow[Max][Max],d[Max]; int vis[Max*3]; int sta,end; vector <int> sum; int min(int a,int b) { if(a<b) return a; else return b; } void dfs(int u) { int i,k; vis[u]=1; for(i=0;i<=end;i++) { if(!vis[i]&&flow[u][i]) dfs(i); } } bool bfs(int s) { int front=0,rear=0; int q[Max*100]; int k,i; memset(d,-1,sizeof(d)); q[rear++]=s; d[s]=0; while(front<rear) { k=q[front++]; for(i=1;i<=end;i++) if(flow[k][i]>0&&d[i]==-1) { d[i]=d[k]+1; q[rear++]=i; } } if(d[end]>=0) return true; return false; } int dinic(int k,int sum) { int i,a; if(k==end) return sum; int os=sum; for(i=1;i<=end&∑i++) if(d[i]==d[k]+1&&flow[k][i]>0) { a=dinic(i,min(sum,flow[k][i])); flow[k][i]-=a; flow[i][k]+=a; sum-=a; } return os-sum; } int main() { int w1[120],w2[120]; int n,m; int i,t; scanf("%d",&t); while(t--) { int x,y; int ans=0; memset(flow,0,sizeof(flow)); scanf("%d%d",&n,&m); sta=0;end=2*n+1; for(i=1;i<=n;i++) scanf("%d",&w1[i]); for(i=1;i<=n;i++) scanf("%d",&w2[i]); for(i=1;i<=n;i++) flow[i+n][end]=w1[i]; for(i=1;i<=n;i++) flow[sta][i]=w2[i]; for(i=1;i<=m;i++) { scanf("%d%d",&x,&y); flow[x][y+n]=INF; } while(bfs(sta)) ans+=dinic(sta,INF); printf("%d\n",ans); memset(vis,0,sizeof(vis)); dfs(0); sum.clear(); for(i=1;i<=n;i++) { if(!vis[i]) sum.push_back(i); if(vis[i+n]) sum.push_back(i+n); } printf("%d\n",sum.size()); for(i=0;i<sum.size();i++) { if(sum[i]<=n) printf("%d-\n",sum[i]); else printf("%d+\n",sum[i]-n); } printf("\n"); } return 0; }