luogu P2756 飞行员配对方案问题
二次联通门 : luogu P2756 飞行员配对方案问题
/* luogu P2756 飞行员配对方案问题 二分图匹配 输出时略麻烦 从源点开始 若扫到的下一条边的流量为0 则证明该条边可以 再枚举当前点的边,记录答案 最后输出即可 */ #include <iostream> #include <cstring> #include <cstdio> #include <queue> #define Max 202 #define INF 1e7 using namespace std; void read (int &now) { now = 0; char word = getchar (); while (word < '0' || word > '9') word = getchar (); while (word >= '0' && word <= '9') { now = now * 10 + word - '0'; word = getchar (); } } struct Edge { int to; int flow; int next; }edge[Max << 5]; int Edge_Count = 1; int edge_list[Max]; int N, M; int S = 0, T; inline void AddEdge (int from, int to) { Edge_Count++; edge[Edge_Count].flow = 1; edge[Edge_Count].to = to; edge[Edge_Count].next = edge_list[from]; edge_list[from] = Edge_Count; Edge_Count++; edge[Edge_Count].flow = 0; edge[Edge_Count].to = from; edge[Edge_Count].next = edge_list[to]; edge_list[to] = Edge_Count; } int deep[Max]; int Flowing (int now, int flow) { if (flow <= 0 || now == T) return flow; int pos, res = 0; for (int i = edge_list[now]; i; i = edge[i].next) { if (deep[edge[i].to] != deep[now] + 1 || edge[i].flow <= 0) continue; pos = Flowing (edge[i].to, min (edge[i].flow, flow)); res += pos; flow -= pos; edge[i].flow -= pos; edge[i ^ 1].flow += pos; if (flow == 0) return res; } return res; } struct Link { int first; int second; }link[Max]; int main (int argc, char *argv[]) { read (M); read (N); T = N + 2; int x, y; while (scanf ("%d%d", &x, &y) && x != -1 && y != -1) AddEdge (x, y); for (int i = 1; i <= M; i++) AddEdge (S, i); for (int i = M + 1; i <= N; i++) AddEdge (i, T); int Answer = 0; while (true) { bool flag = false; memset (deep, -1, sizeof deep); queue <int> Queue; Queue.push (S); deep[S] = 0; int now; while (!Queue.empty ()) { now = Queue.front (); Queue.pop (); for (int i = edge_list[now]; i; i = edge[i].next) if (deep[edge[i].to] < 0 && edge[i].flow) { deep[edge[i].to] = deep[now] + 1; if (edge[i].to == T) { flag = true; break; } Queue.push (edge[i].to); } if (flag) break; } if (deep[T] < 0) break; Answer += Flowing (S, INF); } if (!Answer) { printf ("No Solution!"); return 0; } printf ("%d\n", Answer); int Count = 0; for (int i = edge_list[S]; i; i = edge[i].next) if (!edge[i].flow) for (int j = edge_list[edge[i].to]; j; j = edge[j].next) if (!edge[j].flow) { if (edge[i].to == T || edge[j].to == S || edge[i].to == S || edge[j].to == T) continue; Count++; link[Count].first = edge[i].to; link[Count].second = edge[j].to; } for (int i = 1; i <= Count; i++) printf ("%d %d\n", link[i].first, link[i].second); return 0; }
myj 吊打我Orz,xxy 捆起来打我Orz,myl 文化课上天Orz, lrh 姿势水平敲高Orz, hkd 特别胖Orz%%%,cys 智商感人Orz,syl zz专业Orz,我没有学上, 我们未来一片光明