hdu4635 有向图最多添加多少边使图仍非强连通
2014-08-03 10:39
267 查看
思路:先缩点成有向无环图,则必然含有出度为0的点/入度为0的点,因为要使添加的边尽量多,最多最多也就n*(n-1)条减去原来的m条边,这样是一个强连通图,问题转化为最少去掉几条,使图不强连通,原来图中入度的点,若不添加入度,则必然不连通,同理出度为0的也一样,所以,找入度/出度为0的点中, ki(n-ki)最小的,这里KI是缩点后该SCC中的点数量,这个结果就是最小去掉的边数了。
思路清晰,1A。
思路清晰,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; }
相关文章推荐
- hdu4635 有向图最多添加多少边使图仍非强连通
- nyoj 120 校园网络(求添加多少条边使整个图强连通)
- 强连通(hdu4635)最多增加几条单向边后满足最终的图形不是强连通
- HDU 4635 —— Strongly connected——————【 强连通、最多加多少边仍不强连通】
- hdu4635(最多加多少边,使得有向图不是强连通图)
- win7 32位支持多大内存|win7 32位旗舰版最多能识别多少内存
- OpenMP对于嵌套循环应该添加多少个parallel for
- Codeforces Round #313 (Div. 2) C. Geralds Hexagon (六边形最多划分多少个正三角形)
- joj1445 棋盘上最多放多少马
- 在一个div内,动态添加一段文字,如何设置为不管内容多少都以 上下垂直居中 的形式展现?
- 求字符串中最多连续出现多少个字符
- LintCode 最多有多少个点在一条直线上
- hidden类型的INPUT最多可以容纳多少字符
- Shell最多支持多少个参数
- LA 4015 树形DP 在路程不超过k的情况下,求最多可到达多少节点
- 测量一次I/0最多能读多少块 【验证db_file_multiblock_read_count的值】
- 题目描述 有这样一道智力题:“某商店规定:三个空汽水瓶可以换一瓶汽水。小张手上有十个空汽水瓶,她最多可以换多少瓶汽水喝?”答案是5瓶,方法如下:先用9个空瓶子换3瓶汽水,喝掉3瓶满的,喝完以后4个空
- JVM最多可创建多少线程
- Linux系统中最多可有多少个进程同时存在
- 测试XP下最多可生产多少条进程(Process)