hdu4635 有向圖最多添加多少邊使圖仍非強連通,hdu4635連通

來源:互聯網
上載者:User

hdu4635 有向圖最多添加多少邊使圖仍非強連通,hdu4635連通

思路:先縮點成有向非循環圖,則必然含有出度為0的點/入度為0的點,因為要使添加的邊盡量多,最多最多也就n*(n-1)條減去原來的m條邊,這樣是一個強連通圖,問題轉化為最少去掉幾條,使圖不強連通,原來圖中入度的點,若不添加入度,則必然不連通,同理出度為0的也一樣,所以,找入度/出度為0的點中, ki(n-ki)最小的,這裡KI是縮點後該SCC中的點數量,這個結果就是最小去掉的邊數了。 

思路清晰,1A。

#include<iostream>#include<vector>#include<cstdio>#include<cstring>#include<stack>using namespace std;int n,m;const int maxv=100030;vector<vector<int> >edges(maxv);int visited[maxv]; int low[maxv];   int dfn[maxv];int ind[maxv];     int outd[maxv];  int sccnum[maxv];int scc[maxv];int num;int times;stack<int>s;int instack[maxv];void tarjan(int u){    low[u]=dfn[u]=times++;    instack[u]=1;    s.push(u);    int len=edges[u].size();    for(int i=0;i<len;i++)    {        int v=edges[u][i];        if(visited[v]==0)        {             visited[v]=1;               tarjan(v);            if(low[u]>low[v])low[u]=low[v];        }        else if(instack[v]&&low[u]>dfn[v])        {            low[u]=dfn[v];        }    }    if(dfn[u]==low[u])         //在一個SCC    {        num++;int temp;int snum=0;         do        {            snum++;             temp=s.top();             instack[temp]=0;            s.pop();            scc[temp]=num;        } while(temp!=u);        sccnum[num]=snum;    }}void readin()            //讀入資料{    scanf("%d%d",&n,&m);    int a,b;    for(int i=1;i<=m;i++)    {        scanf("%d%d",&a,&b);        edges[a].push_back(b);    }}void initialize(){    num=times=0;    for(int i=0;i<=100000;i++)    {        dfn[i]=low[i]=ind[i]=outd[i]=visited[i]=sccnum[i]=scc[i]=0;        edges[i].clear();    }}int solve(){    for(int i=1;i<=n;i++)       if(visited[i]==0)        {            visited[i]=1;            tarjan(i);        }    if(num==1){return -1;}     for(int i=1;i<=n;i++)   {       int len=edges[i].size();       for(int j=0;j<len;j++)       {          int v=edges[i][j];          if(scc[v]!=scc[i])          {            outd[scc[i]]++;            ind[scc[v]]++;          }       }    }    int mincut=1000000000;    for(int i=1;i<=num;i++)    {       int temp=0;       if(outd[i]==0||ind[i]==0)       {           temp=sccnum[i]*(n-sccnum[i]);           if(temp<mincut)mincut=temp;       }    }    return n*(n-1)-m-mincut;}int main(){    int T;    cin>>T;int cases=1;    while(T--)    {        initialize();       readin();      int ans=solve();     printf("Case %d: %d\n",cases++,ans);    }   return 0;}



n個頂點的強連通圖至少有多少條邊?這樣的有向圖是什形狀?

強連通圖必須從任何一點出發都可以回到原處,每個節點至少要一條出路(單節點除外)
至少有n條邊,正好可以組成一個環
 
一個有向圖要怎添加邊,使得其成為一個強連通圖,知道要添加max(入度為0點的個數,出度為0點的個數)

15.在一個有向圖中,所有頂點的入度之和等於所有弧數和___倍。 A 、1 B、2 C、3 D、4 A 、1 在有向圖的鄰接表中,從一頂點出發的
 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.