欧美三区_成人在线免费观看视频_欧美极品少妇xxxxⅹ免费视频_a级毛片免费播放_鲁一鲁中文字幕久久_亚洲一级特黄

最小點割集(點連通度)

系統 1729 0


????? 無向(有向)圖G中,給定源點s和終點t,至少要刪去多少個點(具體一點,刪哪些點),使得s和t不連通。這個問題就是 點連通度 ,也叫 最小點割集 。

???? 一般最小點割轉化到最小邊割上,將原圖中的點v拆成v'和v'',且w(v,v'')=1。對于原圖中的有向邊(u,v),則有w(u'',v')=INF;若是無向邊,則還要加上邊:w(v'',v')=INF。然后求以s''為源點,t'為匯點的最大流。 maxflow即為最少需要刪的點數,割邊集對應了具體刪的點的一組解

???? 值得 注意 的是最小點割的解有很多,如下圖:



?

最小點割集(點連通度)

?

???? 最小點割的方案有4種:(4,3),(4,1),(2,3),(2,1)。若按上述方法求解,最小割點集為(4,3)。

?

例: POJ1815

???? 題意: 給出一個圖,問要刪去多少個點,才能使得從1到不了n。顯然這是個最小點割問題。但題目又要求,如果有多種方案,輸出序號最小的一種。

???? 解: 顯然,如果s和t直接相連,則無解。求最小點割集方法并不難,取割邊集即可,關鍵是如何滿足題意"序號最小的一種"。有一種簡單的貪心:從2到n-1枚舉刪除每一個點,看刪除之后流量是否發生變化,若變化,則這點就算在解中;否則恢復這個點。過程一直進行到maxflow=0為止。

    #include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>
using namespace std;
const int INF = 0x7fffffff;
const int maxv = 410;
const int maxe = maxv*maxv*10;
int n;
int g[205][205];
struct Edge
{
    int v;
    int next;
    int flow;
};
Edge e[maxe];
int head[maxv],edgeNum;
int now[maxv],d[maxv],vh[maxv],pre[maxv],preh[maxv];
int result[maxv];
bool cut[maxv];

void addEdge(int a,int b,int c)
{
    e[edgeNum].v = b;
    e[edgeNum].flow = c;
    e[edgeNum].next = head[a];
    head[a] = edgeNum++;
    e[edgeNum].v = a;
    e[edgeNum].flow = 0;
    e[edgeNum].next = head[b];
    head[b] = edgeNum++;
}

void Init()
{
    edgeNum = 0;
    memset(head,-1,sizeof(head));
    memset(d,0,sizeof(d));
}

int sap(int s,int t,int n)       //源點,匯點,結點總數
{
    int i,x,y;
    int f,ans = 0;
    for(i = 0; i < n; i++)
        now[i] = head[i];
    vh[0] = n;
    x = s;
    while(d[s] < n)
    {
        for(i = now[x]; i != -1; i = e[i].next)
            if(e[i].flow > 0 && d[y=e[i].v] + 1 == d[x])
                break;
            if(i != -1)
            {
                now[x] = preh[y] = i;
                pre[y] = x;
                if((x=y) == t)
                {
                    for(f = INF,i=t; i != s; i = pre[i])
                        if(e[preh[i]].flow < f)
                            f = e[preh[i]].flow;
                    ans += f;
                    do
                    {
                        e[preh[x]].flow -= f;
                        e[preh[x]^1].flow += f;
                        x = pre[x];
                    }while(x!=s);
                }
            }
            else
            {
                if(!--vh[d[x]])
                    break;
                d[x] = n;
                for(i=now[x]=head[x]; i != -1; i = e[i].next)
                {
                    if(e[i].flow > 0 && d[x] > d[e[i].v] + 1)
                    {
                        now[x] = i;
                        d[x] = d[e[i].v] + 1;
                    }
                }
                ++vh[d[x]];
                if(x != s)
                    x = pre[x];
            }
    }
    return ans;
}

void makeGraph()
{
    int i,j;
    Init();
    for(i = 1; i <= n; i++)
    {
        for(j = 1; j <= n; j++)
        {
            if(g[i][j])
            {
                addEdge(i+n,j,INF);
                addEdge(j+n,i,INF);
            }
        }
    }
    for(i = 1; i <= n; i++)
    {
        if(!cut[i])
            addEdge(i,i+n,1);
        else
            addEdge(i,i+n,0);
    }
}

int main()
{
    int i,j;
    int s,t;
    scanf("%d %d %d",&n,&s,&t);
    memset(cut,0,sizeof(cut));
    for(i = 1; i <= n; i++)
        for(j = 1; j <= n; j++)
            scanf("%d",&g[i][j]);
    if(g[s][t])
    {
        printf("NO ANSWER!");
        return 0;
    }
    makeGraph();
    int flow = sap(s+n,t,2*n);
    printf("%d\n",flow);
    int cnt = 0;
    for(i = 1; i <= n && flow; i++)
    {
        if(i==s||i==t)
            continue;
        cut[i] = true;
        makeGraph();
        if(sap(s+n,t,2*n) == flow-1)
        {
            flow--;
            result[cnt++] = i;
        }
        else
            cut[i] = false;
    }
    for(i = 0; i < cnt; i++)
        printf("%d ",result[i]);
    printf("\n");
    return 0;
}
  

?

?

最小點割集(點連通度)


更多文章、技術交流、商務合作、聯系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號聯系: 360901061

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對您有幫助就好】

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長會非常 感謝您的哦!!!

發表我的評論
最新評論 總共0條評論
主站蜘蛛池模板: 操美女在线 | www.色网站| 亚洲黄色在线视频 | 欧美亚洲视频在线观看 | 亚洲成av人在线视 | 成人全黄三级视频在线观看 | 一级黄色毛片 | 亚洲品质自拍视频 | 咪咪色在线视频 | 夜操| 三级视频网站 | 欧美激情视频二区三区 | 啪啪免费网站入口链接 | www.天天操.com | 国产亚洲精品久久久久久老妇 | 色淫湿视频 | 久久9966e这里只有精品 | 青草视频在线 | 国产福利视频一区 | 天天综合网在线观看视频 | 日本精品久久久久久久 | 欧美中文字幕一区二区 | 欧美精品一区二区在线电影 | 黄色a视频 | 人成免费a级毛片 | 男女同床爽爽视频免费 | 国产福利不卡视频在免费 | 96久久久久久 | 五月天综合在线 | 北京一级毛片 | 亚洲一区二区三 | 中文字幕av一区二区 | 国产一级一区 | 色艹 | 免费的黄色网 | 在线欧美 | 天天爽天天草 | 亚洲精品人成网在线播放影院 | 欧美高清极品videossex | 一级毛片片 | 在线观看国产精品一区 |