hdu3639 强连通+缩点 tarjan算法
来源:互联网 发布:python win32api 截屏 编辑:程序博客网 时间:2024/05/01 02:18
http://acm.split.hdu.edu.cn/showproblem.php?pid=3639
题意:投票:如果A投给B,B投给C,那么C也会得到A的投票。现在要求谁的票最多,并输出这些人的编号。
题解:跑tarjan求强连通分量,在强连通分量的队伍中,每个点都是相互投票的。那么对原图进行缩点,然后反向建图。选出入度为0的队伍进行dfs,求出有队伍投给了这个队伍。将总人数求和减去自己即可。最后输出在这个队伍的人的编号。
代码:
#include<set>#include<map>#include<queue>#include<vector>#include<string>#include<bitset>#include<algorithm>#include<cstring>#include<cstdio>#include<cmath>#include<ctime>#include<iomanip>#include<iostream>#define debug cout<<"aaa"<<endl#define d(a) cout<<a<<endl#define mem(a,b) memset(a,b,sizeof(a))#define LL long long#define lson l,mid,root<<1#define rson mid+1,r,root<<1|1#define MIN_INT (-2147483647-1)#define MAX_INT 2147483647#define MAX_LL 9223372036854775807i64#define MIN_LL (-9223372036854775807i64-1)using namespace std;const int N = 100000 + 5;const int mod = 1000000000 + 7;const double eps = 1e-8;int n,m,x[N],y[N];int head[N],len;int dfn[N],low[N],dfs_num;//dfn表示遍历深度,low(u)为u或u的子树能够追溯到的最早的栈中节点的次序号int color[N],col_num,num[N];//染色 int stack[N],vis[N],top;//栈和栈指针int in[N],sum[N],cas=0;struct EdgeNode{ int to,next;}edge[N];void add(int i,int j){ edge[len].to=j; edge[len].next=head[i]; head[i]=len++;} void init(){ mem(dfn,0),mem(low,0),mem(head,-1),len=top=col_num=dfs_num=0;}void tarjan(int x){ dfn[x]=low[x]=++dfs_num; vis[x]=1; stack[++top]=x; for(int i=head[x];i!=-1;i=edge[i].next){ int temp=edge[i].to; if(!dfn[temp]){ tarjan(temp); low[x]=min(low[x],low[temp]); } else if(vis[temp]){ low[x]=min(dfn[temp],low[x]); } } if(dfn[x]==low[x]){//构成强连通分量 vis[x]=0; //染色 color[x]=++col_num; num[col_num]=1; while(stack[top]!=x){//退栈 color[stack[top]]=col_num; num[col_num]++; vis[stack[top]]=0; top--; } top--; }}int dfs(int u){ vis[u]=1; int temp=num[u]; for(int k=head[u];k!=-1;k=edge[k].next){ int v=edge[k].to; if(!vis[v]){ temp+=dfs(v); } } return temp;}void solve(){ for(int i=0;i<n;i++){ if(!dfn[i]){ tarjan(i); } } mem(head,-1),mem(in,0),mem(sum,0),len=0; for(int i=1;i<=m;i++){ if(color[x[i]]!=color[y[i]]){ add(color[y[i]],color[x[i]]); in[color[x[i]]]++; } } int ans=-1; for(int i=1;i<=col_num;i++){ if(in[i]==0){ mem(vis,0); //记录得票数 sum[i]+=dfs(i); ans=max(ans,sum[i]); } } printf("Case %d: %d\n",++cas,ans-1); bool flag=1; for(int i=0;i<n;i++){ if(sum[color[i]]==ans){ if(flag){ printf("%d",i); flag=0; } else{ printf(" %d",i); } } } puts("");}int main(){ int t; scanf("%d",&t); while(t--){ scanf("%d%d",&n,&m); init(); for(int i=1;i<=m;i++){ scanf("%d%d",&x[i],&y[i]); add(x[i],y[i]); } solve(); } return 0;}
阅读全文
0 0
- hdu3639 强连通+缩点 tarjan算法
- PKU2186(Popular Cows)+强连通分支Tarjan算法+缩点
- HDU4635(Strongly connected)Tarjan算法,强连通+缩点
- 强连通分量及缩点tarjan算法解析
- 强连通分量及缩点tarjan算法解析
- poj2186Popular Cows_ 强连通分支_缩点tarjan算法
- tarjan算法缩点&&求强连通分量【转载】
- POJ2186 Tarjan强连通分量+缩点
- tarjan+缩点+强连通定理
- Tarjan求强连通(缩点)
- Tarjan求强连通分量 缩点
- tarjan强连通分量缩点笔记
- 强连通算法--Tarjan
- HDU3639--Hawk-and-Chicken(强连通+缩点+反向图)
- HDU3639 Hawk-and-Chicken 强连通+缩点+建反向图
- 图论复习之强连通分量以及缩点—Tarjan算法
- HDU ACM 1827 Summer Holiday->强连通分量+缩点(tarjan算法)
- POJ 2186 Popular Cows(强连通分量缩点,Tarjan算法)
- HDU 4738 浅谈无向图边双连通求TarJAn求桥及如何“炸桥”
- Matlab安装过程中显示“插入DVD2以继续”弹窗的解决方法(简单快速)
- 正则表达式
- Android View深入解析(一)基础知识VelocityTracker,GestureDetector,Scroller
- 线性表综合实验—单链表
- hdu3639 强连通+缩点 tarjan算法
- windows命令行一些基础mysql命令
- 数论——【模板】线性筛素数
- Python 多线程运行多个job的框架
- 点云PCL估计一个点云的表面法线
- Leetcode (一)——数组:Remove Duplicates from Sorted Array II
- Banner轮播图
- NOIP2016 天天爱跑步 (LCA,树上差分)
- 电脑桌面没有图标怎么办?