亚洲免费在线-亚洲免费在线播放-亚洲免费在线观看-亚洲免费在线观看视频-亚洲免费在线看-亚洲免费在线视频

最小點割集(點連通度)

系統 1892 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條評論
主站蜘蛛池模板: 中文视频在线观看 | 亚洲国产综合自在线另类 | 国产欧美日韩中文字幕 | 久久香蕉国产线 | 热久久这里只有 | 久久国产加勒比精品无码 | 欧美性大战久久久久久久蜜桃 | 国产网红自拍 | 日本一级片在线观看 | 天天拍夜夜拍 | 国产精品不卡在线 | 国产免费一级精品视频 | 久热这里只精品99国产6_99 | 国产99精品视频 | 在线不卡一区 | 国产精品一区伦免视频播放 | 亚洲精品一区久久狠狠欧美 | 久草热视频在线 | 亚洲国产精品二区久久 | 国产精品久久久久免费a∨ 国产精品久久久久免费视频 | 国产高清一区二区三区 | 按摩一级片 | 日韩免费一区二区三区 | 波多野给衣一区二区三区 | 久久亚洲一级α片 | 伊人365| 四虎视频网站 | 在线视频 国产交换 | 久草在线视频资源站 | 青草社区视频 | 欧美在线观看高清一二三区 | 欧美一区二区三区视频在线观看 | 久久亚洲精中文字幕冲田杏梨 | 羞羞视频免费观看网站 | 色综合久久中文字幕网 | 98精品国产综合久久 | 9966久久精品免费看国产 | 国产香蕉在线精彩视频 | 欧美日韩性视频在线 | 久久综合色之久久综合 | 国产色综合网 |