标签:二分答案 before stream rds nbsp nes pre ace sed
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 4248 Accepted Submission(s): 1406
S-girl和boy-T连边,容量n;
girl和所有能匹配的boy连边,容量1;
然后跑一次最大流,答案为S-girl和boy-T的边中流量的最小值。
1 3 4 0 1 2 2 1 2 3 3 2 答案应该是0,但用上述方法答案为1。
1 //2017-08-25 2 #include <cstdio> 3 #include <cstring> 4 #include <iostream> 5 #include <algorithm> 6 #include <queue> 7 #include <vector> 8 #define mid ((l+r)>>1) 9 10 using namespace std; 11 12 const int N = 510; 13 const int M = 100000; 14 const int INF = 0x3f3f3f3f; 15 int head[N], tot; 16 struct Edge{ 17 int next, to, w; 18 }edge[M]; 19 20 void add_edge(int u, int v, int w){ 21 edge[tot].w = w; 22 edge[tot].to = v; 23 edge[tot].next = head[u]; 24 head[u] = tot++; 25 26 edge[tot].w = 0; 27 edge[tot].to = u; 28 edge[tot].next = head[v]; 29 head[v] = tot++; 30 } 31 32 struct Dinic{ 33 int level[N], S, T; 34 void init(int _S, int _T){ 35 S = _S; 36 T = _T; 37 tot = 0; 38 memset(head, -1, sizeof(head)); 39 } 40 bool bfs(){ 41 queue<int> que; 42 memset(level, -1, sizeof(level)); 43 level[S] = 0; 44 que.push(S); 45 while(!que.empty()){ 46 int u = que.front(); 47 que.pop(); 48 for(int i = head[u]; i != -1; i = edge[i].next){ 49 int v = edge[i].to; 50 int w = edge[i].w; 51 if(level[v] == -1 && w > 0){ 52 level[v] = level[u]+1; 53 que.push(v); 54 } 55 } 56 } 57 return level[T] != -1; 58 } 59 int dfs(int u, int flow){ 60 if(u == T)return flow; 61 int ans = 0, fw; 62 for(int i = head[u]; i != -1; i = edge[i].next){ 63 int v = edge[i].to, w = edge[i].w; 64 if(!w || level[v] != level[u]+1) 65 continue; 66 fw = dfs(v, min(flow-ans, w)); 67 ans += fw; 68 edge[i].w -= fw; 69 edge[i^1].w += fw; 70 if(ans == flow)return ans; 71 } 72 if(ans == 0)level[u] = 0; 73 return ans; 74 } 75 int maxflow(){ 76 int flow = 0; 77 while(bfs()) 78 flow += dfs(S, INF); 79 return flow; 80 } 81 }dinic; 82 83 bool G[N][N]; 84 int T, n, m, f; 85 int never_quarreled[M][2], friends[M][2]; 86 void build_graph(int cap){ 87 int s = 0, t = 2*n+1; 88 dinic.init(s, t); 89 memset(G, 0, sizeof(G)); 90 int a, b; 91 for(int i = 0; i < m; i++){ 92 a = never_quarreled[i][0]; 93 b = never_quarreled[i][1]; 94 add_edge(a, n+b, 1); 95 G[a][b] = 1; 96 } 97 for(int i = 0; i < f; i++){ 98 a = friends[i][0]; 99 b = friends[i][1]; 100 for(int i = head[a]; i != -1; i = edge[i].next){ 101 int v = edge[i].to; 102 if(!G[b][v-n] && v != s && v != t){ 103 add_edge(b, v, 1); 104 G[b][v-n] = 1; 105 } 106 } 107 for(int i = head[b]; i != -1; i = edge[i].next){ 108 int v = edge[i].to; 109 if(!G[a][v-n] && v != s && v != t){ 110 add_edge(a, v, 1); 111 G[a][v-n] = 1; 112 } 113 } 114 } 115 for(int i = 1; i <= n; i++){ 116 add_edge(s, i, cap); 117 add_edge(n+i, t, cap); 118 } 119 } 120 121 int main() 122 { 123 std::ios::sync_with_stdio(false); 124 //freopen("inputN.txt", "r", stdin); 125 cin>>T; 126 while(T--){ 127 cin>>n>>m>>f; 128 for(int i = 0; i < m; i++) 129 cin>>never_quarreled[i][0]>>never_quarreled[i][1]; 130 for(int i = 0; i < f; i++) 131 cin>>friends[i][0]>>friends[i][1]; 132 int l = 0, r = n, ans = 0; 133 while(l <= r){ 134 build_graph(mid); 135 int flow = dinic.maxflow(); 136 if(flow == mid*n){ 137 ans = mid; 138 l = mid+1; 139 }else{ 140 r = mid-1; 141 } 142 } 143 cout<<ans<<endl; 144 } 145 return 0; 146 }
标签:二分答案 before stream rds nbsp nes pre ace sed
原文地址:http://www.cnblogs.com/Penn000/p/7427115.html