日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

pku 1486 求出二分匹配图中的必须边

發布時間:2025/7/14 编程问答 26 豆豆
生活随笔 收集整理的這篇文章主要介紹了 pku 1486 求出二分匹配图中的必须边 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

開始楞是沒看懂意思,E文讓我很糾結...

要判斷一條邊是否為二分圖中必須邊,方法如下:

1、先求出原圖的任意最大匹配

2、對二分圖某一邊的所有點,刪去其當前的匹配邊。刪的過程不是簡單的將原圖設為不連通,你還得將其相應的匹配值設為未匹配。

假如原圖link[a]=b;? 那我們刪邊的時候既要講map[b][a]設為0.,同時也要講link[a]設為-1。(舉個例子而已,數據的寫法自己定)

3、對此跟新圖再次從b點(承接上面的例子)進行一次最大匹配,如果此時還能完成最大匹配,那么剛才刪去的那條邊顯然就不是必須邊了。反之,必須邊成立!(做完記得將圖還原)

4、重復2步驟,直到所有的點都被刪過了一次當前匹配邊

(還有一個問題就是,再對跟新圖進行最大匹配驗證的過程中,這必然不可避免的會改變其他匹配邊原來的信息。比如a點原來匹配著b點,在新方案中,它可能卻變成了匹配c點。其實這對我們的算法沒有任何影響,因為我們本來的目的就只是對點進行匹配,至于該點和那個點匹配,無所謂。最開始,我們也是任意的進行了一次二分匹配。我們刪邊的目的只是為了驗證該點是不是還存在著其他匹配方案,至于是從哪一個方案變到哪一個方案,沒有任何關系)

View Code #include<iostream>
#include
<string>
using namespace std;

int link[30];
int map[30][30];
typedef
struct node
{
int xmin;
int xmax;
int ymin;
int ymax;
}node;

node num[
30];
int n,m;
int v[30];

int find(int x)
{
for(int i=1;i<=n;i++)
{
if(!v[i] && map[x][i])
{
v[i]
=1;
if(link[i]==0 || find(link[i]))
{
link[i]
=x;
return 1;
}
}
}
return 0;
}

void solve()
{
int i;
memset(link,
0,sizeof(link));
for(i=1;i<=n;i++)
{
memset(v,
0,sizeof(v));
find(i);
}
}


int isok(int x,int y,int i)
{
if(x>=num[i].xmin && x<=num[i].xmax && y>=num[i].ymin && y<=num[i].ymax)
return 1;
return 0;
}

int main()
{
int i,j,a,b;m=1;
freopen(
"D:\\in.txt","r",stdin);
while(scanf("%d",&n),n)
{
for(i=1;i<=n;i++)
{
scanf(
"%d%d%d%d",&num[i].xmin,&num[i].xmax,&num[i].ymin,&num[i].ymax);
}
memset(map,
0,sizeof(map));
for(i=1;i<=n;i++)
{
scanf(
"%d%d",&a,&b);
for(j=1;j<=n;j++)
{
if(isok(a,b,j))
{
map[i][j]
=1; //左邊代表數字,右邊代表字母
}
}
}

//先任意求一次最大匹配
solve();
printf(
"Heap %d\n",m++);
int flag=0;
for(i=1;i<=n;i++)
{
if(!link[i])
continue;
int temp=link[i];
link[i]
=0; //把位置騰出來
map[temp][i]=0; //同時把邊刪掉,這樣就無法達到原來的匹配
memset(v,0,sizeof(v));
if(!find(temp)) //如果沒有新的匹配方案誕生,說明這是一條關鍵邊
{
if(flag)
cout
<<" ";
flag
=1;
link[i]
=temp;
printf(
"(%c,%d)",(char)(i+64),temp);
}
map[temp][i]
=1; //把圖復原
}
if(!flag)
{
cout
<<"none";
}
cout
<<endl<<endl;
}
return 0;
}

轉載于:https://www.cnblogs.com/ka200812/archive/2011/07/30/2121866.html

《新程序員》:云原生和全面數字化實踐50位技術專家共同創作,文字、視頻、音頻交互閱讀

總結

以上是生活随笔為你收集整理的pku 1486 求出二分匹配图中的必须边的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。