input | output |
---|---|
3 1 2 2 3 1 3 |
2 1 2
|
模板题!!!
以下是模板:
1 /* *********************************************** 2 Author :kuangbin 3 Created Time :2013/8/21 22:56:05 4 File Name :F:\2013ACM练习\专题学习\图论\一般图匹配带花树\URAL1099.cpp 5 ************************************************ */ 6 7 #include <stdio.h> 8 #include <string.h> 9 #include <iostream> 10 #include <algorithm> 11 #include <vector> 12 #include <queue> 13 #include <set> 14 #include <map> 15 #include <string> 16 #include <math.h> 17 #include <stdlib.h> 18 #include <time.h> 19 using namespace std; 20 21 const int MAXN = 250; 22 int N; //点的个数,点的编号从1到N 23 bool Graph[MAXN][MAXN]; 24 int Match[MAXN]; 25 bool InQueue[MAXN],InPath[MAXN],InBlossom[MAXN]; 26 int Head,Tail; 27 int Queue[MAXN]; 28 int Start,Finish; 29 int NewBase; 30 int Father[MAXN],Base[MAXN]; 31 int Count;//匹配数,匹配对数是Count/2 32 void CreateGraph() 33 { 34 int u,v; 35 memset(Graph,false,sizeof(Graph)); 36 scanf("%d",&N); 37 while(scanf("%d%d",&u,&v) == 2) 38 { 39 Graph[u][v] = Graph[v][u] = true; 40 } 41 } 42 void Push(int u) 43 { 44 Queue[Tail] = u; 45 Tail++; 46 InQueue[u] = true; 47 } 48 int Pop() 49 { 50 int res = Queue[Head]; 51 Head++; 52 return res; 53 } 54 int FindCommonAncestor(int u,int v) 55 { 56 memset(InPath,false,sizeof(InPath)); 57 while(true) 58 { 59 u = Base[u]; 60 InPath[u] = true; 61 if(u == Start) break; 62 u = Father[Match[u]]; 63 } 64 while(true) 65 { 66 v = Base[v]; 67 if(InPath[v])break; 68 v = Father[Match[v]]; 69 } 70 return v; 71 } 72 void ResetTrace(int u) 73 { 74 int v; 75 while(Base[u] != NewBase) 76 { 77 v = Match[u]; 78 InBlossom[Base[u]] = InBlossom[Base[v]] = true; 79 u = Father[v]; 80 if(Base[u] != NewBase) Father[u] = v; 81 } 82 } 83 void BloosomContract(int u,int v) 84 { 85 NewBase = FindCommonAncestor(u,v); 86 memset(InBlossom,false,sizeof(InBlossom)); 87 ResetTrace(u); 88 ResetTrace(v); 89 if(Base[u] != NewBase) Father[u] = v; 90 if(Base[v] != NewBase) Father[v] = u; 91 for(int tu = 1; tu <= N; tu++) 92 if(InBlossom[Base[tu]]) 93 { 94 Base[tu] = NewBase; 95 if(!InQueue[tu]) Push(tu); 96 } 97 } 98 void FindAugmentingPath() 99 { 100 memset(InQueue,false,sizeof(InQueue)); 101 memset(Father,0,sizeof(Father)); 102 for(int i = 1;i <= N;i++) 103 Base[i] = i; 104 Head = Tail = 1; 105 Push(Start); 106 Finish = 0; 107 while(Head < Tail) 108 { 109 int u = Pop(); 110 for(int v = 1; v <= N; v++) 111 if(Graph[u][v] && (Base[u] != Base[v]) && (Match[u] != v)) 112 { 113 if((v == Start) || ((Match[v] > 0) && Father[Match[v]] > 0)) 114 BloosomContract(u,v); 115 else if(Father[v] == 0) 116 { 117 Father[v] = u; 118 if(Match[v] > 0) 119 Push(Match[v]); 120 else 121 { 122 Finish = v; 123 return; 124 } 125 } 126 } 127 } 128 } 129 void AugmentPath() 130 { 131 int u,v,w; 132 u = Finish; 133 while(u > 0) 134 { 135 v = Father[u]; 136 w = Match[v]; 137 Match[v] = u; 138 Match[u] = v; 139 u = w; 140 } 141 } 142 void Edmonds() 143 { 144 memset(Match,0,sizeof(Match)); 145 for(int u = 1; u <= N; u++) 146 if(Match[u] == 0) 147 { 148 Start = u; 149 FindAugmentingPath(); 150 if(Finish > 0)AugmentPath(); 151 } 152 } 153 void PrintMatch() 154 { 155 Count = 0; 156 for(int u = 1; u <= N;u++) 157 if(Match[u] > 0) 158 Count++; 159 printf("%d\n",Count); 160 for(int u = 1; u <= N; u++) 161 if(u < Match[u]) 162 printf("%d %d\n",u,Match[u]); 163 } 164 int main() 165 { 166 CreateGraph();//建图 167 Edmonds();//进行匹配 168 PrintMatch();//输出匹配数和匹配 169 return 0; 170 }