poj 2125
最小点权覆盖。
注意入边,出边不要搞反了。
代码:
#include<iostream> #include<fstream> #include<queue> using namespace std; int n; int d[210]; int flow; int v[210]; typedef struct e{ int data; int f,c; e *next,*opt; }e; e edge[210]; int build(){ int i,j,k; queue<int> q; q.push(1); memset(d,0,sizeof(d)); d[1]=1; while(!q.empty()) { i=q.front(); q.pop(); e *p=edge[i].next; while(p) { j=p->data; if(d[j]==0&&p->c>p->f) { d[j]=d[i]+1; if(j==n) return 1; q.push(j); } p=p->next; } } return 0; } int find(int m,int minw){ int i,k; int j; if(m==n) return minw; v[m]=1; e *p=edge[m].next; while(p) { i=p->data; if(p->c>p->f&&d[i]==d[m]+1&&v[i]==0) { j=find(i,min(minw,p->c-p->f)); if(j) { p->f+=j; p->opt->f=p->f*(-1); return j; } } p=p->next; } return 0; } int solve(){ int j; int k; flow=0; int i; while(build()) while(1){ memset(v,0,sizeof(v)); i=10000000; k=find(1,i); flow+=k; if(k==0) break; } return flow; } void dfs(int s){ e *p=edge[s].next; v[s]=1; while(p){ if(!v[p->data]&&p->c>p->f) dfs(p->data); p=p->next; } } void read(){ // ifstream cin("in.txt"); int i,j,k,s,t,m; int value; cin>>n>>m; for(i=1;i<=n;i++) { cin>>value; e *p=new e; p->data=i+1; p->next=edge[1].next; edge[1].next=p; p->c=value; p->f=0; e *q=new e; q->data=1; q->next=edge[i+1].next; edge[i+1].next=q; q->c=q->f=0; p->opt=q; q->opt=p; } for(i=1;i<=n;i++) { cin>>value; e *p=new e; p->data=i+n+1; p->next=edge[n+n+2].next; edge[n+n+2].next=p; p->c=0; p->f=0; e *q=new e; q->data=n+n+2; q->next=edge[i+1+n].next; edge[i+1+n].next=q; q->f=0;q->c=value; p->opt=q; q->opt=p; } for(i=1;i<=m;i++) { cin>>t>>s; e *p=new e; p->data=t+1+n; p->next=edge[1+s].next; edge[1+s].next=p; p->c=10000000; p->f=0; e *q=new e; q->data=1+s; q->next=edge[t+n+1].next; edge[t+n+1].next=q; q->c=q->f=0; p->opt=q; q->opt=p; } n+=2+n; solve(); printf("%d\n",flow); int ans=0; memset(v,0,sizeof(v)); dfs(1); e *p=edge[1].next; while(p){ if(!v[p->data]) ans++; p=p->next; } p=edge[n].next; while(p){ if(v[p->data]) ans++; p=p->next; } cout<<ans<<endl; p=edge[1].next; while(p){ if(!v[p->data]) cout<<p->data-1<<" +"<<endl; p=p->next; } p=edge[n].next; while(p){ if(v[p->data]) cout<<p->data-n/2<<" -"<<endl; p=p->next; } } int main(){ read(); return 0; }