HDOJ 4635: Strongly connected 【强连通】
来源:互联网 发布:延长月经周期 知乎 编辑:程序博客网 时间:2024/06/09 20:35
题意:图中有n个点,m条有向边。保证不含有自环和重边
问:我们最多可以添加多少条边,使得原图不是强连通的
首先:
去掉不是强连通的条件:我们可以添加的总边数为:n*(n-1)-m
所以:如果原图已经是强连通了:那么答案为-1
需要特判吗?
不需要!那么该题第一步就是用模板,缩点强连通
如果缩点后只有一个集合,那么输出-1(说明原图已经强连通)
然后,我们应该如何构造出最多的边?其实就是删掉最少的边。
考虑到点的总数为n,是个定值,要使得删掉的边最少,那么其实分成两个集合,每个集合中的边全部连完毕(是个完全图)
然后从A集合到B集合,要么全是出边,要么全是入边,并且使得A中点数和B中点数差别越大越好(因为数学结论:两数之和相等,差越大,成绩越小)
所以,枚举缩点后的每个集合中的点数,找到最小的那个x,乘以(n-x)
求点数只需要在模板里加一句就好了
得到答案:n*(n-1)-m-x*(n-x)
代码如下:
#include<bits/stdc++.h>using namespace std;#define LL __int64const int maxn=100050;vector<int> g[maxn];vector<int> rg[maxn];vector<int> vs;int n,m,u,v;bool used[maxn];int cmp[maxn];int num[maxn];int outdegree[maxn];int indegree[maxn];void addedge(int u,int v){ g[u].push_back(v); rg[v].push_back(u);}void dfs(int v){ used[v]=true; for(int i=0;i<g[v].size();i++) if (!used[g[v][i]]) dfs(g[v][i]); vs.push_back(v);}void rdfs(int v,int k){ used[v]=true; cmp[v]=k; num[k]++; for(int i=0;i<rg[v].size();i++) if (!used[rg[v][i]]) rdfs(rg[v][i],k);}int scc(){ memset(used,0,sizeof(used)); vs.clear(); for(int v=0;v<n;v++) if (!used[v]) dfs(v); memset(used,0,sizeof(used)); int k=0; for(int i=vs.size()-1;i>=0;i--) if (!used[vs[i]]) rdfs(vs[i],k++); return k;}int main(){ //freopen("input.txt","r",stdin); int T; scanf("%d",&T); for(int Case=1;Case<=T;Case++){ memset(outdegree,0,sizeof(outdegree)); memset(indegree,0,sizeof(indegree)); memset(num,0,sizeof(num)); memset(cmp,0,sizeof(cmp)); scanf("%d%d",&n,&m); for(int i=0;i<=n;i++){ g[i].clear(); rg[i].clear(); } for(int i=1;i<=m;i++){ scanf("%d%d",&u,&v); addedge(u-1,v-1); } int tot=scc(); //printf("tot:%d\n",tot); //for(int i=0;i<tot;i++) // printf("%d%c",num[i],i==tot-1?'\n':' '); //for(int i=0;i<n;i++) // printf("%d%c",cmp[i],i==n-1?'\n':' '); if (tot==1){ printf("Case %d: -1\n",Case); continue; } LL ans=0; for(int i=0;i<n;i++) for(int j=0;j<g[i].size();j++){ u=cmp[i]; v=cmp[g[i][j]]; if (u!=v){ outdegree[u]++; indegree[v]++; } } for(int i=0;i<tot;i++) if (outdegree[i]==0||indegree[i]==0) ans=max(ans,1LL*n*(n-1)-1LL*num[i]*(n-num[i])-m); printf("Case %d: %I64d\n",Case,ans); } return 0;}
0 0
- HDOJ 4635: Strongly connected 【强连通】
- hdu 4635 Strongly connected 强连通
- hdu 4635 Strongly connected (强连通分量)
- hdu-4635-Strongly connected-强连通分量
- HDU 4635 Strongly connected 强连通
- HDU 4635 Strongly connected(强连通分量)
- 【强连通】 HDU 4635 Strongly connected
- HDU 4635 - Strongly connected(强连通)
- HDU 4635 Strongly connected(强连通)
- HDU 4635 Strongly connected 强连通
- HDU 4635 Strongly connected(强连通)经典
- HDU 4635 Strongly connected(强连通分量)
- HDU4635 Strongly connected【强连通】
- HDOJ 4635: Strongly connected
- hdu 4635 Strongly connected (tarjan强连通分量)
- hdu 4635 Strongly connected(强连通+缩点)
- hdu 4635 Strongly connected (强连通分量缩点)
- HDU 4635 Strongly connected(强连通分量+缩点)
- 51nod-1433 0和5
- Android studio上如何使用gitHub?
- JavaScript/Jsp 多图上传和上传Excelx表到数据库
- TypeScript 接口
- 357. Count Numbers with Unique Digits
- HDOJ 4635: Strongly connected 【强连通】
- 算法学习之动态规划(leetcode 304. Range Sum Query 2D - Immutable)
- 游艇租用
- SSM搭建-Maven创建第一个web项目(22-1)
- 两个矩阵相乘—Strassen算法与传统算法(要求矩阵阶n为2的幂)
- tomcat添加https访问支持
- SSM框架项目搭建系列(五)—Spring之Bean的注解注入
- git:拉库的指定分支
- LeetCode No.45 Jump Game II