标签:
3 3 3 1 10 2 1 2 2 2 1 3 3 1 2 6
7
建模题,这里需要注意对空间的优化。
1 #include <iostream> 2 #include <cstring> 3 #include <cstdio> 4 #include <queue> 5 6 using namespace std; 7 const int INF=2147483647; 8 const int maxn=1010,maxm=4010; 9 int cnt,fir[maxn],nxt[maxm],cap[maxm],to[maxm],dis[maxn],gap[maxn],path[maxn],used[maxn]; 10 11 void addedge(int a,int b,int c) 12 { 13 nxt[++cnt]=fir[a]; 14 to[cnt]=b; 15 cap[cnt]=c; 16 fir[a]=cnt; 17 } 18 19 bool BFS(int S,int T) 20 { 21 memset(dis,0,sizeof(dis)); 22 dis[T]=1; 23 queue<int>q;q.push(T); 24 while(!q.empty()) 25 { 26 int node=q.front();q.pop(); 27 for(int i=fir[node];i;i=nxt[i]) 28 { 29 if(dis[to[i]])continue; 30 dis[to[i]]=dis[node]+1; 31 q.push(to[i]); 32 } 33 } 34 return dis[S]; 35 } 36 int fron[maxn]; 37 int ISAP(int S,int T) 38 { 39 if(!BFS(S,T)) 40 return 0; 41 for(int i=1;i<=T;i++)++gap[dis[i]]; 42 int p=S,ret=0; 43 memcpy(fron,fir,sizeof(fir)); 44 while(dis[S]<=T) 45 { 46 if(p==T){ 47 int f=INF; 48 while(p!=S){ 49 f=min(f,cap[path[p]]); 50 p=to[path[p]^1]; 51 } 52 p=T;ret+=f; 53 while(p!=S){ 54 cap[path[p]]-=f; 55 cap[path[p]^1]+=f; 56 p=to[path[p]^1]; 57 } 58 } 59 int &ii=fron[p]; 60 for(;ii;ii=nxt[ii]){ 61 if(!cap[ii]||dis[to[ii]]+1!=dis[p]) 62 continue; 63 else 64 break; 65 } 66 if(ii){ 67 p=to[ii]; 68 path[p]=ii; 69 } 70 else{ 71 if(--gap[dis[p]]==0)break; 72 int minn=T+1; 73 for(int i=fir[p];i;i=nxt[i]) 74 if(cap[i]) 75 minn=min(minn,dis[to[i]]); 76 gap[dis[p]=minn+1]++; 77 fron[p]=fir[p]; 78 if(p!=S) 79 p=to[path[p]^1]; 80 } 81 } 82 return ret; 83 } 84 85 void Init() 86 { 87 memset(fir,0,sizeof(fir)); 88 memset(used,0,sizeof(used)); 89 cnt=1; 90 } 91 int main() 92 { 93 int n,m,num,k,need; 94 while(~scanf("%d%d",&m,&n)) 95 { 96 Init(); 97 for(int i=1;i<=m;i++){ 98 scanf("%d",&num); 99 addedge(0,i,num); 100 addedge(i,0,0); 101 } 102 for(int i=m+1;i<=m+n;i++){ 103 scanf("%d",&k); 104 while(k--){ 105 scanf("%d",&num); 106 if(used[num]){ 107 addedge(used[num],i,INF); 108 addedge(i,used[num],0); 109 } 110 else{ 111 used[num]=i; 112 addedge(num,i,INF); 113 addedge(i,num,0); 114 } 115 116 } 117 scanf("%d",&need); 118 addedge(i,n+m+1,need); 119 addedge(n+m+1,i,0); 120 } 121 printf("%d\n",ISAP(0,n+m+1)); 122 } 123 return 0; 124 }
标签:
原文地址:http://www.cnblogs.com/TenderRun/p/5222626.html