首页 > 代码库 > POJ2289-Jamie's Contact Groups-二分图多重匹配-ISAP
POJ2289-Jamie's Contact Groups-二分图多重匹配-ISAP
注意POJ数组越界可能返回TLE!!!
网络流的maxn大小要注意
其他没什么了 裸二分答案+isap乱搞
不过复杂度没搞懂 V=1e3 E = 1e5 那ISAP的O(V^2E)怎么算都不行啊
1 /*--------------------------------------------------------------------------------------*/ 2 3 #include <algorithm> 4 #include <iostream> 5 #include <cstring> 6 #include <ctype.h> 7 #include <cstdlib> 8 #include <cstdio> 9 #include <vector> 10 #include <string> 11 #include <queue> 12 #include <stack> 13 #include <cmath> 14 #include <set> 15 #include <map> 16 17 //debug function for a N*M array 18 #define debug_map(N,M,G) printf("\n");for(int i=0;i<(N);i++) 19 {for(int j=0;j<(M);j++){ 20 printf("%d",G[i][j]);}printf("\n");} 21 //debug function for int,float,double,etc. 22 #define debug_var(X) cout<<#X"="<<X<<endl; 23 #define LL long long 24 const int INF = 0x3f3f3f3f; 25 const LL LLINF = 0x3f3f3f3f3f3f3f3f; 26 /*--------------------------------------------------------------------------------------*/ 27 using namespace std; 28 29 int N,M,T; 30 const int maxn = 2010; 31 const int maxm = 2000010; 32 //map<int ,string > mp; 33 vector <int> save[maxn]; 34 35 struct Edge{ 36 int to,next,cap,flow; 37 }edge[maxm]; 38 39 int head[maxn],tot; 40 int uN = 0; 41 int gap[maxn],dep[maxn],pre[maxn],cur[maxn]; 42 43 void init() 44 { 45 tot = 0; 46 memset(head,-1,sizeof head); 47 } 48 49 void add_edge(int u,int v,int w,int rw = 0) 50 { 51 //printf("%d->%d %d\n",u,v,w); 52 edge[tot].to = v;edge[tot].cap = w;edge[tot].next = head[u]; 53 edge[tot].flow = 0;head[u] = tot++; 54 edge[tot].to = u;edge[tot].cap = rw;edge[tot].next = head[v]; 55 edge[tot].flow = 0;head[v] = tot++; 56 } 57 int Q[maxn]; 58 void BFS(int st,int ed) 59 { 60 memset(dep,-1,sizeof dep); 61 memset(gap,0,sizeof gap); 62 gap[0] = 1; 63 int front = 0,rear = 0; 64 dep[ed] = 0; 65 Q[rear++] = ed; 66 while(front != rear) 67 { 68 int u = Q[front++]; 69 for(int i=head[u];~i;i=edge[i].next) 70 { 71 int v = edge[i].to; 72 if(dep[v] != -1) continue; 73 Q[rear++] = v; 74 dep[v] = dep[u] + 1; 75 gap[dep[v]] ++; 76 } 77 } 78 } 79 int S[maxn]; 80 81 int sap(int st,int ed) 82 { 83 BFS(st,ed); 84 memcpy(cur,head,sizeof head); 85 int top = 0; 86 int u = st; 87 88 int ans = 0; 89 while(dep[st] < uN) 90 { 91 if(u == ed) 92 { 93 int Min = INF; 94 int inser; 95 for(int i=0;i<top;i++) 96 { 97 if(Min > edge[S[i]].cap - edge[S[i] ].flow) 98 { 99 Min = edge[S[i]].cap - edge[S[i]].flow;100 inser=i;101 }102 }103 for(int i=0;i<top;i++)104 {105 edge[S[i]].flow += Min;106 edge[S[i]^1].flow -= Min;107 }108 ans += Min;109 top = inser;110 u = edge[S[top]^1].to;111 continue;112 }113 bool flag = false;114 int v;115 for(int i=cur[u];~i;i=edge[i].next)116 {117 v = edge[i].to;118 if(edge[i].cap - edge[i].flow && dep[v]+1 == dep[u])119 {120 flag = true;121 cur[u] = i;122 break;123 }124 }125 if(flag)126 {127 S[top++] = cur[u];128 u = v;129 continue;130 }131 int Min = uN;132 for(int i=head[u];~i;i=edge[i].next)133 {134 if(edge[i].cap - edge[i].flow && dep[edge[i].to] < Min)135 {136 Min = dep[edge[i].to];137 cur[u] = i;138 }139 }140 gap[dep[u]] --;141 if(!gap[dep[u]]) return ans;142 dep[u] = Min + 1;143 gap[dep[u] ]++;144 if(u != st) u = edge[S[--top]^1].to;145 }146 return ans;147 }148 149 int check(int mid)150 {151 uN = N+M+2;152 init();153 for(int i=0;i<N;i++)154 {155 add_edge(N+M,i,1);156 for(int j=0;j<save[i].size();j++)157 {158 add_edge(i,save[i][j]+N,1);159 }160 }161 for(int i=0;i<M;i++)162 {163 add_edge(N+i,N+M+1,mid);164 }165 166 int res = sap(N+M,N+M+1);167 //printf("mid:%d res:%d\n",mid,res);168 if(res == N) return true;169 else return false;170 }171 172 int solve()173 {174 int L = 0,R = 2*N,mid;175 while(L <= R)176 {177 mid = (L+R)>>1;178 if(check(mid)) R = mid-1;179 else L = mid+1;180 }181 //printf("%d %d\n",L,R);182 return L;183 }184 185 int main()186 {187 while(scanf("%d%d",&N,&M) && N+M)188 {189 char s[20];190 //mp.clear();191 for(int i=0;i<maxn;i++) save[i].clear();192 for(int i=0;i<N;i++)193 {194 scanf("%s",s);195 char c = getchar();196 if(c != ‘ ‘) continue;197 int num = -1;198 while((c = getchar()) && c !=‘\n‘)199 {200 if(isdigit(c))201 {202 if(num == -1) num = 0;203 num *= 10;num += c-‘0‘;204 }205 else if(c == ‘ ‘)206 {207 save[i].push_back(num);208 num = -1;209 }210 }211 if(num != -1) save[i].push_back(num);212 }213 if(M == 0 || N == 0) printf("0\n");214 else printf("%d\n",solve());215 }216 }
POJ2289-Jamie's Contact Groups-二分图多重匹配-ISAP
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。