G - Strongly connected - hdu 4635(求连通分量)
生活随笔
收集整理的這篇文章主要介紹了
G - Strongly connected - hdu 4635(求连通分量)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
題意:給你一個圖,問最多能添加多少條邊使圖仍為不是強連通圖,如果原圖是強連通輸出 ‘-1’分析:先把求出連通分量進行縮點,因為是求最多的添加邊,所以可以看成兩部分 x,y,只能一部分向另外一部分連邊,內部的就是完全圖,所以是x*(x+1)+x*y+y*(y+1)-M,只需要求出來出度或者入度為0的最少點的那個連通分量即可。**********************************************************************#include<stdio.h>
#include<string.h>
#include<algorithm>
using?namespace?std;
const?int?MAXN?=?1e5+5;
const?int?oo?=?1e9;
struct?Edge{int?v,?next;}e[MAXN];
int?Head[MAXN],?cnt;
void?AddEdge(int?u,?int?v)
{
????e[cnt].v?=?v;
????e[cnt].next?=?Head[u];
????Head[u]?=?cnt++;
}
int?dfn[MAXN],?low[MAXN],?Index;
int?Stack[MAXN],?top,?inStack[MAXN];
int?blg[MAXN],?bnt,?nblg[MAXN];///屬于哪個連通分量,連通分量里面有幾個點
int?outEdge[MAXN],?inEdge[MAXN];
void?InIt(int?N)
{
????cnt?=?Index?=?top?=?bnt?=?0;
????for(int?i=0;?i<=N;?i++)
????{
????????Head[i]?=?-1;
????????dfn[i]?=?0;
????????nblg[i]?=?0;
????????outEdge[i]?=?0;
????????inEdge[i]?=?0;
????}
}
void?Tarjan(int?u)
{
????int?v;
????low[u]?=?dfn[u]?=?++Index;
????Stack[++top]?=?u;
????inStack[u]?=?true;
????for(int?j=Head[u];?j!=-1;?j=e[j].next)
????{
????????v?=?e[j].v;
????????if(?!dfn[v]?)
????????{
????????????Tarjan(v);
????????????low[u]?=?min(low[u],?low[v]);
????????}
????????else?if(inStack[v]?==?true)
????????????low[u]?=?min(low[u],?dfn[v]);
????}
????if(low[u]?==?dfn[u])
????{
????????++bnt;
????????do
????????{
????????????v?=?Stack[top--];
????????????inStack[v]?=?false;
????????????blg[v]?=?bnt;
????????????nblg[bnt]++;
????????}
????????while(u?!=?v);
????}
}
int?main()
{
????int?T,?t=1;
????scanf("%d",?&T);
????while(T--)
????{
????????int?i,?j,?u,?v,?N,?M;
????????scanf("%d%d",?&N,?&M);
????????InIt(N);
????????for(i=0;?i<M;?i++)
????????{
????????????scanf("%d%d",?&u,?&v);
????????????AddEdge(u,?v);
????????}
????????for(i=1;?i<=N;?i++)
????????{
????????????if(?!dfn[i]?)
????????????????Tarjan(i);
????????}
????????for(i=1;?i<=N;?i++)
????????for(j=Head[i];?j!=-1;?j=e[j].next)
????????{
????????????v?=?e[j].v;
????????????if(blg[i]?!=?blg[v])
????????????{
????????????????inEdge[?blg[v]?]++;
????????????????outEdge[?blg[i]?]++;
????????????}
????????}
????????int?x,?y=oo;
????????for(i=1;?i<=bnt;?i++)
????????{
????????????if(!outEdge[i]?||?!inEdge[i])
????????????????y?=?min(y,?nblg[i]);
????????}
????????x?=?N-y;
????????if(bnt?==?1)
????????????printf("Case?%d:?-1\n",?t++);
????????else
????????????printf("Case?%d:?%lld\n",t++,?(long?long)x*(x-1)+x*y+y*(y-1)-M);
????}
????return?0;?
#include<string.h>
#include<algorithm>
using?namespace?std;
const?int?MAXN?=?1e5+5;
const?int?oo?=?1e9;
struct?Edge{int?v,?next;}e[MAXN];
int?Head[MAXN],?cnt;
void?AddEdge(int?u,?int?v)
{
????e[cnt].v?=?v;
????e[cnt].next?=?Head[u];
????Head[u]?=?cnt++;
}
int?dfn[MAXN],?low[MAXN],?Index;
int?Stack[MAXN],?top,?inStack[MAXN];
int?blg[MAXN],?bnt,?nblg[MAXN];///屬于哪個連通分量,連通分量里面有幾個點
int?outEdge[MAXN],?inEdge[MAXN];
void?InIt(int?N)
{
????cnt?=?Index?=?top?=?bnt?=?0;
????for(int?i=0;?i<=N;?i++)
????{
????????Head[i]?=?-1;
????????dfn[i]?=?0;
????????nblg[i]?=?0;
????????outEdge[i]?=?0;
????????inEdge[i]?=?0;
????}
}
void?Tarjan(int?u)
{
????int?v;
????low[u]?=?dfn[u]?=?++Index;
????Stack[++top]?=?u;
????inStack[u]?=?true;
????for(int?j=Head[u];?j!=-1;?j=e[j].next)
????{
????????v?=?e[j].v;
????????if(?!dfn[v]?)
????????{
????????????Tarjan(v);
????????????low[u]?=?min(low[u],?low[v]);
????????}
????????else?if(inStack[v]?==?true)
????????????low[u]?=?min(low[u],?dfn[v]);
????}
????if(low[u]?==?dfn[u])
????{
????????++bnt;
????????do
????????{
????????????v?=?Stack[top--];
????????????inStack[v]?=?false;
????????????blg[v]?=?bnt;
????????????nblg[bnt]++;
????????}
????????while(u?!=?v);
????}
}
int?main()
{
????int?T,?t=1;
????scanf("%d",?&T);
????while(T--)
????{
????????int?i,?j,?u,?v,?N,?M;
????????scanf("%d%d",?&N,?&M);
????????InIt(N);
????????for(i=0;?i<M;?i++)
????????{
????????????scanf("%d%d",?&u,?&v);
????????????AddEdge(u,?v);
????????}
????????for(i=1;?i<=N;?i++)
????????{
????????????if(?!dfn[i]?)
????????????????Tarjan(i);
????????}
????????for(i=1;?i<=N;?i++)
????????for(j=Head[i];?j!=-1;?j=e[j].next)
????????{
????????????v?=?e[j].v;
????????????if(blg[i]?!=?blg[v])
????????????{
????????????????inEdge[?blg[v]?]++;
????????????????outEdge[?blg[i]?]++;
????????????}
????????}
????????int?x,?y=oo;
????????for(i=1;?i<=bnt;?i++)
????????{
????????????if(!outEdge[i]?||?!inEdge[i])
????????????????y?=?min(y,?nblg[i]);
????????}
????????x?=?N-y;
????????if(bnt?==?1)
????????????printf("Case?%d:?-1\n",?t++);
????????else
????????????printf("Case?%d:?%lld\n",t++,?(long?long)x*(x-1)+x*y+y*(y-1)-M);
????}
????return?0;?
}
?
轉載于:https://www.cnblogs.com/liuxin13/p/4693700.html
《新程序員》:云原生和全面數字化實踐50位技術專家共同創作,文字、視頻、音頻交互閱讀總結
以上是生活随笔為你收集整理的G - Strongly connected - hdu 4635(求连通分量)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: SQL Server 2005中更改sa
- 下一篇: category、protocol、de