HDU 4687 Boke and Tsukkomi (一般图匹配带花树)

Boke and Tsukkomi

Time Limit: 3000/3000 MS (Java/Others)    Memory Limit: 102400/102400 K (Java/Others)
Total Submission(s): 336    Accepted Submission(s): 116


Problem Description
A new season of Touhou M-1 Grand Prix is approaching. Girls in Gensokyo cannot wait for participating it. Before the registration, they have to decide which combination they are going to compete as. Every girl in Gensokyo is both a boke (funny girl) and a tsukkomi (straight girl). Every candidate combination is made up of two girls, a boke and a tsukkomi. A girl may belong to zero or more candidate combinations, but one can only register as a member of one formal combination. The host of Touhou M-1 Grand Prix hopes that as many formal combinations as possible can participate in this year. Under these constraints, some candidate combinations are actually redundant as it\'s impossible to register it as a formal one as long as the number of formal combinations has to be maximized. So they want to figure out these redundant combinations and stop considering about them.
HDU 4687 Boke and Tsukkomi (一般图匹配带花树)
 

 

Input
There are multiple test cases. Process to the End of File.
The first line of each test case contains two integers: 1 ≤ N ≤ 40 and 1 ≤ M ≤  123, where N is the number of girls in Gensokyo, and M is the number of candidate combinations. The following M lines are M candidate combinations, one by each line. Each combination is represented by two integers, the index of the boke girl 1 ≤ B i ≤ N and the index of the tsukkomi girl 1 ≤ T i ≤ N, where B i != T i.
 

 

Output
For each test case, output the number of redundant combinations in the first line. Then output the space-separated indexes of the redundant combinations in ascending order in the second line.
 

 

Sample Input
4 4 1 3 2 3 2 4 3 1 6 6 1 2 3 2 3 4 5 2 5 4 5 6
 

 

Sample Output
1 2 3 2 4 5
 

 

Author
Zejun Wu (watashi)
 

 

Source
 

 

Recommend
zhuyuanchen520
 
 
 
 
 
 
 
 
基本上就是一般图匹配的模板题了。
 
 
先一开始算总的匹配对数为cnt0.
然后枚举每一对匹配,把该对的点去掉,看匹配数是不是小于cnt0-1,是就是多余的。
 
  1 /* ***********************************************

  2 Author        :kuangbin

  3 Created Time  :2013/8/23 19:28:08

  4 File Name     :F:\2013ACM练习\专题学习\图论\一般图匹配带花树\HDU4687.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 const int MAXN = 50;

 21 int N; //点的个数,点的编号从1到N

 22 bool Graph[MAXN][MAXN];

 23 int Match[MAXN];

 24 bool InQueue[MAXN],InPath[MAXN],InBlossom[MAXN];

 25 int Head,Tail;

 26 int Queue[MAXN];

 27 int Start,Finish;

 28 int NewBase;

 29 int Father[MAXN],Base[MAXN];

 30 int Count;

 31 void Push(int u)

 32 {

 33     Queue[Tail] = u;

 34     Tail++;

 35     InQueue[u] = true;

 36 }

 37 int Pop()

 38 {

 39     int res = Queue[Head];

 40     Head++;

 41     return res;

 42 }

 43 int FindCommonAncestor(int u,int v)

 44 {

 45     memset(InPath,false,sizeof(InPath));

 46     while(true)

 47     {

 48         u = Base[u];

 49         InPath[u] = true;

 50         if(u == Start) break;

 51         u = Father[Match[u]];

 52     }

 53     while(true)

 54     {

 55         v = Base[v];

 56         if(InPath[v])break;

 57         v = Father[Match[v]];

 58     }

 59     return v;

 60 }

 61 void ResetTrace(int u)

 62 {

 63     int v;

 64     while(Base[u] != NewBase)

 65     {

 66         v = Match[u];

 67         InBlossom[Base[u]] = InBlossom[Base[v]] = true;

 68         u = Father[v];

 69         if(Base[u] != NewBase) Father[u] = v;

 70     }

 71 }

 72 void BloosomContract(int u,int v)

 73 {

 74     NewBase = FindCommonAncestor(u,v);

 75     memset(InBlossom,false,sizeof(InBlossom));

 76     ResetTrace(u);

 77     ResetTrace(v);

 78     if(Base[u] != NewBase) Father[u] = v;

 79     if(Base[v] != NewBase) Father[v] = u;

 80     for(int tu = 1; tu <= N; tu++)

 81         if(InBlossom[Base[tu]])

 82         {

 83             Base[tu] = NewBase;

 84             if(!InQueue[tu]) Push(tu);

 85         }

 86 }

 87 void FindAugmentingPath()

 88 {

 89     memset(InQueue,false,sizeof(InQueue));

 90     memset(Father,0,sizeof(Father));

 91     for(int i = 1;i <= N;i++)

 92         Base[i] = i;

 93     Head = Tail = 1;

 94     Push(Start);

 95     Finish = 0;

 96     while(Head < Tail)

 97     {

 98         int u = Pop();

 99         for(int v = 1; v <= N; v++)

100             if(Graph[u][v] && (Base[u] != Base[v]) && (Match[u] != v))

101             {

102                 if((v == Start) || ((Match[v] > 0) && Father[Match[v]] > 0))

103                     BloosomContract(u,v);

104                 else if(Father[v] == 0)

105                 {

106                     Father[v] = u;

107                     if(Match[v] > 0)

108                         Push(Match[v]);

109                     else

110                     {

111                         Finish = v;

112                         return;

113                     }

114                 }

115             }

116     }

117 }

118 void AugmentPath()

119 {

120     int u,v,w;

121     u = Finish;

122     while(u > 0)

123     {

124         v = Father[u];

125         w = Match[v];

126         Match[v] = u;

127         Match[u] = v;

128         u = w;

129     }

130 }

131 void Edmonds()

132 {

133     memset(Match,0,sizeof(Match));

134     for(int u = 1; u <= N; u++)

135         if(Match[u] == 0)

136         {

137             Start = u;

138             FindAugmentingPath();

139             if(Finish > 0)AugmentPath();

140         }

141 }

142 int getMatch()

143 {

144     Edmonds();

145     Count = 0;

146     for(int u = 1; u <= N;u++)

147         if(Match[u] > 0)

148             Count++;

149     return Count/2;

150 }

151 

152 bool g[MAXN][MAXN];

153 pair<int,int>p[150];

154 int main()

155 {

156     //freopen("in.txt","r",stdin);

157     //freopen("out.txt","w",stdout);

158     int m;

159     while(scanf("%d%d",&N,&m)==2)

160     {

161         memset(g,false,sizeof(g));

162         memset(Graph,false,sizeof(Graph));

163         int u,v;

164         for(int i = 1;i <= m;i++)

165         {

166             scanf("%d%d",&u,&v);

167             p[i] = make_pair(u,v);

168             g[u][v] = true;

169             g[v][u] = true;

170             Graph[u][v] = true;

171             Graph[v][u] = true;

172         }

173         int cnt0 = getMatch();

174         //cout<<cnt0<<endl;

175         vector<int>ans;

176         for(int i = 1;i <= m;i++)

177         {

178             u = p[i].first;

179             v = p[i].second;

180             memcpy(Graph,g,sizeof(g));

181             for(int j = 1;j <= N;j++)

182                 Graph[j][u] = Graph[u][j] = Graph[j][v] = Graph[v][j] = false;

183             int cnt = getMatch();

184             //cout<<cnt<<endl;

185             if(cnt < cnt0-1)

186                 ans.push_back(i);

187         }

188         int sz = ans.size();

189         printf("%d\n",sz);

190         for(int i = 0;i < sz;i++)

191         {

192             printf("%d",ans[i]);

193             if(i < sz-1)printf(" ");

194         }

195         printf("\n");

196     }

197     return 0;

198 }

 

 
 
 
 
 
 
 
 
 
 
 
 

你可能感兴趣的:(HDU)