HDU - 4687 Boke and Tsukkomi(一般图最大匹配-带花图)
生活随笔
收集整理的這篇文章主要介紹了
HDU - 4687 Boke and Tsukkomi(一般图最大匹配-带花图)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
題目鏈接:點擊查看
題目大意:給出n個人和m對匹配,現在問有多少組匹配是不必要的,按照升序輸出答案
題目分析:因為題目給的N比較小,所以一開始我的想法是先計算出最大匹配,而后枚舉每一條邊被刪除,然后計算最大匹配,如果匹配結果等于最大匹配,則說明這條吧是不必要的,儲存答案即可,樣例過了但是卻WA了,有點自閉,后來只能向網上清一色的看不懂的寫法妥協,具體就是每次將枚舉的邊的兩個端點從圖中刪除,若計算出的最大匹配小于原最大匹配-1,則說明這條邊是不必須的,原理不明,可能是我一開始就沒看懂題,掛上來主要是看代碼,題目不重要
對于這個題有坑,最后的答案可能是0,不判斷一下的話會出現RE或PE
代碼:
#include<iostream> #include<cstdio> #include<string> #include<ctime> #include<cstring> #include<algorithm> #include<stack> #include<queue> #include<map> #include<set> #include<sstream> using namespace std;typedef long long LL;const int inf=0x3f3f3f3f;const int N=505;const int M=N*N*2;int n,m,que[M],ql,qr,pre[N],tim=0;struct Edge {int v,nxt,u; }e[M],edge[M];int h[N],tot=0;int match[N],f[N],tp[N],tic[N];bool can[N];int find(int x) {return f[x]==x?f[x]:f[x]=find(f[x]); }void addedge(int u,int v) {e[++tot]=(Edge){v,h[u],0};h[u]=tot; }int lca(int x,int y) {for (++tim;;swap(x,y)) if(x) {x=find(x);if(tic[x]==tim) return x; else {tic[x]=tim;x=pre[match[x]];}} }void shrink(int x,int y,int p) {while(find(x)!=p) {pre[x]=y;y=match[x];if(tp[y]==2) {tp[y]=1;que[++qr]=y;}if(find(x)==x) f[x]=p;if(find(y)==y) f[y]=p;x=pre[y];} }bool aug(int s) {for(int i=1;i<=n;++i) f[i]=i;memset(tp,0,sizeof tp);memset(pre,0,sizeof pre);tp[que[ql=qr=1]=s]=1; // 1: type A ; 2: type Bint t=0;while(ql<=qr) {int x=que[ql++];for(int i=h[x],v=e[i].v;i;i=e[i].nxt,v=e[i].v) {if(find(v)==find(x)||tp[v]==2||can[v]||can[x]) continue; if(!tp[v]) {tp[v]=2;pre[v]=x;if(!match[v]) {for(int now=v,last,tmp;now;now=last) {last=match[tmp=pre[now]];match[now]=tmp,match[tmp]=now;}return true;} tp[match[v]]=1,que[++qr]=match[v];} else if(tp[v]==1) {int l=lca(x,v);shrink(x,v,l);shrink(v,x,l);}}} return false; }int solve() {memset(match,0,sizeof(match));memset(tic,0,sizeof(tic));int ans=0;for(int i=1;i<=n;i++)if(!match[i]&&aug(i))ans++;return ans; }void init() {tot=0;memset(h,0,sizeof(h));memset(can,false,sizeof(can)); }int main() { // freopen("input.txt","r",stdin);int m;while(scanf("%d%d",&n,&m)!=EOF){init();for(int i=1;i<=m;i++){scanf("%d%d",&edge[i].u,&edge[i].v);addedge(edge[i].u,edge[i].v);addedge(edge[i].v,edge[i].u);}int cnt=solve();vector<int>ans;for(int i=1;i<=m;i++){can[edge[i].u]=can[edge[i].v]=true;int temp=solve();if(temp<cnt-1)ans.push_back(i);can[edge[i].u]=can[edge[i].v]=false;}printf("%d\n",ans.size());if(ans.size()){printf("%d",ans[0]);for(int i=1;i<ans.size();i++)printf(" %d",ans[i]);}printf("\n");}return 0; }?
總結
以上是生活随笔為你收集整理的HDU - 4687 Boke and Tsukkomi(一般图最大匹配-带花图)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: URAL - 1099 Work Sch
- 下一篇: HDU - 4513 吉哥系列故事——完