zoj 2429 Destroying The Graph 最小点权覆盖

来源:互联网 发布:java线程池代码 编辑:程序博客网 时间:2024/06/07 03:57
 
#include <cstdio>#include <string.h>#include <vector>using namespace std;#define Max 230#define INF 100000000int 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;}

0 0