hdu 4687 Boke and Tsukkomi(一般图匹配 带花树算法)
来源:互联网 发布:js base64 key 编辑:程序博客网 时间:2024/05/18 02:15
Boke and Tsukkomi
Time Limit: 3000/3000 MS (Java/Others) Memory Limit: 102400/102400 K (Java/Others)Total Submission(s): 739 Accepted Submission(s): 231
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.
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 ≤ Bi ≤ N and the index of the tsukkomi girl 1 ≤ Ti ≤ N, where Bi != Ti.
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 ≤ Bi ≤ N and the index of the tsukkomi girl 1 ≤ Ti ≤ N, where Bi != Ti.
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 41 32 32 43 16 61 23 23 45 25 45 6
Sample Output
1232 4 5
首先用带花树匹配求出 最大匹配数mmg 然后在枚举每一个匹配 删除这个匹配 再求匹配数
如果不等于mmg-1 则这个匹配是多余的
#include <cstdio>#include <iostream>#include <cstring>#include <cmath>#include <algorithm>#include <string.h>#include <string>#include <vector>#include <queue>#define MEM(a,x) memset(a,x,sizeof a)#define eps 1e-8#define MOD 10009#define MAXN 200#define INF 99999999#define ll __int64#define bug cout<<"here"<<endl#define fread freopen("ceshi.txt","r",stdin)#define fwrite freopen("out.txt","w",stdout)using namespace std;int Read(){ char ch; int a = 0; while((ch = getchar()) == ' ' | ch == '\n'); a += ch - '0'; while((ch = getchar()) != ' ' && ch != '\n') { a *= 10; a += ch - '0'; } return a;}void Print(int a) //输出外挂{ if(a>9) Print(a/10); putchar(a%10+'0');}deque<int> Q;//g[i][j]存放关系图:i,j是否有边 match[i]存放i所匹配的点bool g[MAXN][MAXN],inque[MAXN],inblossom[MAXN],inpath[MAXN];int match[MAXN],pre[MAXN],base[MAXN];int n,m,mmg;vector<int> res;struct node{ int u,v;}point[MAXN];//找公共祖先int findancestor(int u,int v){ MEM(inpath,0); while(1) { u=base[u]; inpath[u]=1; if(match[u]==-1) break; u=pre[match[u]]; } while(1) { v=base[v]; if(inpath[v]) return v; v=pre[match[v]]; }}//压缩花void reset(int u,int anc){ while(u!=anc) { int v=match[u]; inblossom[base[u]]=1; inblossom[base[v]]=1; v=pre[v]; if(base[v]!=anc) pre[v]=match[u]; u=v; }}void contract(int u,int v,int n){ int anc=findancestor(u,v); MEM(inblossom,0); reset(u,anc); reset(v,anc); if(base[u]!=anc) pre[u]=v; if(base[v]!=anc) pre[v]=u; for(int i=1;i<=n;i++) { if(inblossom[base[i]]) { base[i]=anc; if(!inque[i]) { Q.push_back(i); inque[i]=1; } } }}bool dfs(int S,int n){ for(int i=0;i<=n;i++) { pre[i]=-1; inque[i]=0; base[i]=i; } Q.clear(); Q.push_back(S); inque[S]=1; while(!Q.empty()) { int u=Q.front(); Q.pop_front(); for(int v=1;v<=n;v++) { if(g[u][v]&&base[v]!=base[u]&&match[u]!=v) { if(v==S||(match[v]!=-1&&pre[match[v]]!=-1)) contract(u,v,n); else if(pre[v]==-1) { pre[v]=u; if(match[v]!=-1) { Q.push_back(match[v]); inque[match[v]]=1; } else { u=v; while(u!=-1) { v=pre[u]; int w=match[v]; match[u]=v; match[v]=u; u=w; } return 1; } } } } } return 0;}int solve(){ int ans=0; MEM(match,-1); for(int i=1;i<=n;i++) if(match[i]==-1&&dfs(i,n)) ans++; return ans;}int main(){ //fread; while(scanf("%d%d",&n,&m)!=EOF) { MEM(g,0); for(int i=1;i<=m;i++) { int u,v; scanf("%d%d",&u,&v); g[u][v]=g[v][u]=1; point[i].u=u; point[i].v=v; } mmg=solve(); res.clear(); for(int i=1;i<=m;i++) { int u=point[i].u; int v=point[i].v; MEM(g,0); for(int j=1;j<=m;j++) { if(i!=j) { int x=point[j].u,y=point[j].v; if(x==u||x==v||y==u||y==v) continue; g[x][y]=g[y][x]=1; } } int k=solve(); if(k!=mmg-1) res.push_back(i); } printf("%d\n",res.size()); for(int i=0;i<res.size();i++) { if(i) printf(" "); printf("%d",res[i]); } printf("\n"); } return 0;}
0 0
- HDU 4687 Boke and Tsukkomi (一般图匹配带花树)
- HDU 4687 Boke and Tsukkomi(一般图匹配|带花树)
- hdu 4687 Boke and Tsukkomi(一般图匹配 带花树算法)
- [HDU 4687]Boke and Tsukkomi[一般图匹配][带花树]
- hdu 4687 Boke and Tsukkomi(一般图匹配)
- HDU 4687 Boke and Tsukkomi(一般图匹配+枚举)
- HDU 4687 Boke and Tsukkomi 一般图匹配
- hdu - 4687 Boke and Tsukkomi(一般图带花树匹配)
- HDU4687-Boke and Tsukkomi(一般图匹配带花树)
- HDOJ 4687 Boke and Tsukkomi 一般图最大匹配带花树+暴力
- HDU 4687 Boke and Tsukkomi【带花树】
- hdu 4687 Boke and Tsukkomi
- Boke and Tsukkomi HDU
- Hdu4687 Boke and Tsukkomi
- 一般图匹配--带花树算法
- hdu 4687 带花树求一般图最大匹配(模板)
- URAL 1099 Work Scheduling(一般图匹配 带花树算法)
- UOJ 一般图的最大匹配(带花树算法模板)
- 对于slidingmenu与viewPage冲突的解决办法
- Android漏洞挖掘工具收集与整理
- Apache Lucene 3.x推荐教程
- 第五周程序阅读(4)
- web.xml中的ServletContextListener
- hdu 4687 Boke and Tsukkomi(一般图匹配 带花树算法)
- 一些设计上的原则
- 从今天开始(4月1号)开始写博,回家了,新的开始,新的挑战,相信自己
- iOS 7/8--uitextfield动态限制输入的字数
- static的作用
- 【leetcode】Excel Sheet Column Number
- C#客户端日志记录
- Maven学习
- 图解CodeSmith使用和实用教程一 - 入门和生成MIS项目实体层代码