HDU 3639 强连通加缩点
来源:互联网 发布:广州淘宝拍摄基地地址 编辑:程序博客网 时间:2024/04/30 04:45
///先瞎做一番试试,我的实力的确是应该好好涨涨了。//总算过了。。。#include<iostream>#include<cstring>#include<cstdio>#include<cstdlib>#include<vector>#include<string>#define inf 0x3f3f3f3f#define maxn 100500using namespace std;int n;//n m 为点数和边数int sum;int head[maxn], edgenum;int minw[maxn];int DFN[maxn], Low[maxn], Stack[maxn], top, Time; //Low[u]是点集{u点及以u点为根的子树} 中(所有反向弧)能指向的(离根最近的祖先v) 的DFN[v]值(即v点时间戳)int taj;//连通分支标号,从1开始int Belong[maxn];//Belong[i] 表示i点属于的连通分支bool Instack[maxn];vector<int> bcc[maxn]; //标号从1开始bool vis[maxn];vector<int>G[maxn];int du[maxn];int gu[maxn];struct Edge{ int from, to, nex; bool sign;//是否为桥}edge[60000];void addedge(int u, int v){//边的起点和终点 Edge E={u, v, head[u], false}; edge[edgenum] = E; head[u] = edgenum++;}void tarjan(int u ,int fa)//求出图的强联通分量{ DFN[u] = Low[u] = ++ Time ; Stack[top ++ ] = u ; Instack[u] = 1 ; for (int i = head[u] ; ~i ; i = edge[i].nex ){ int v = edge[i].to ; if(DFN[v] == -1) { tarjan(v , u) ; Low[u] = min(Low[u] ,Low[v]) ; if(DFN[u] < Low[v]) { edge[i].sign = 1;//为割桥 } } else if(Instack[v]) Low[u] = min(Low[u] ,DFN[v]) ; } if(Low[u] == DFN[u]){ int now; taj ++ ;bcc[taj].clear(); do{ now = Stack[-- top] ; Instack[now] = 0 ; Belong [now] = taj ; bcc[taj].push_back(now); }while(now != u) ; }}void tarjan_init(int all){ memset(DFN, -1, sizeof(DFN)); memset(Instack, 0, sizeof(Instack)); top = Time = taj = 0; for(int i=1;i<=all;i++)if(DFN[i]==-1 )tarjan(i, i); //注意开始点标!!!}void suodian()////还要更新出入度。。{ memset(du, 0, sizeof(du)); memset(gu,0,sizeof(gu)); memset(minw,0,sizeof(minw)); for(int i = 1; i <= taj; i++)G[i].clear(); for(int i = 0; i < edgenum; i++){ int u = Belong[edge[i].from], v = Belong[edge[i].to]; if(u!=v)G[v].push_back(u), du[u]++,gu[v]++;///g[u]存的是出度,du[v]存的是入度 } for(int i=1;i<=n;i++) minw[Belong[i]]++;}void init(){memset(head, -1, sizeof(head)); edgenum=0;}///遍历图、、建反向图然后深搜。。void dfs(int u)///入度为0的点。。{ vis[u]=true; sum+=minw[u]; for(int i=0;i<G[u].size();i++) { if(!vis[G[u][i]]) dfs(G[u][i]); }//反向建图是因为要找的是可到达该点的强连同分量。。}int allans[maxn];int TOT[maxn];void solve(){ memset(allans,0,sizeof(allans)); int maxx=0;int index=0; for(int i=1;i<=taj;i++) { if(du[i]==0) { memset(vis,false,sizeof(vis)); sum=0; dfs(i); allans[i]=sum; if(allans[i]>maxx) { index=i; maxx=allans[i]; } } } cout<<maxx-1<<endl; int tot=0;// cout<<taj<<" taj"<<endl;// for(int i=1;i<=n;i++)// cout<<Belong[i]<<endl;// cout<<"测试。。。"<<endl;// cout<<index<<endl;// for(int i=1;i<=n;i++)// if(Belong[i]==index)// cout<<i<<" ";// cout<<endl;// cout<<"-----------------------------"<<endl; for(int i=1;i<=n;i++) { if(allans[Belong[i]]==maxx) TOT[++tot]=i; } for(int i=1;i<tot;i++) cout<<TOT[i]-1<<" "; cout<<TOT[tot]-1<<endl;}int main(){// freopen("inn.txt","r",stdin); int cas,a,b; scanf("%d",&cas); int ca=0; while(cas--) { ca++; init(); int m; scanf("%d%d",&n,&m); while(m--) { scanf("%d%d",&a,&b); a++,b++; addedge(a,b); } tarjan_init(n); suodian(); cout<<"Case "<<ca<<": "; solve(); }}
0 0
- HDU 3639 强连通加缩点
- HDU 1827 强连通加缩点
- hdu 3639(强连通分量+dfs)
- hdu 1269 强连通
- hdu 3594 (强连通)
- hdu 3072(强连通分量)
- hdu 2767(强连通分量)
- hdu 1269 强连通分量
- HDU 1827 强连通分量
- HDU 1269 强连通分量
- hdu-4612-强连通分量
- HDU 3594 Cactus 强连通
- HDU 3836&&HDU2767 强连通
- hdu 4365 tarjan强连通
- HDU 2767 强连通分量
- hdu 2767强连通分量
- HDU 1236 强连通分量
- hdu 1827强连通分量
- mac 设置字体
- Eclipse安装SVN插件
- LinearLayout$LayoutParams cannot be cast to android.widget.AbsListView$LayoutParams
- ifconfig没有ipv4地址
- SystemTap–Linux下的万能观测工具
- HDU 3639 强连通加缩点
- Create groups 与 Create folder references
- Linux服务器性能评估
- 【转帖】易飞ERP 9.05版本 包含EasyFlow工作流注册机
- js公司测试题(公司做手游)
- POJ 2513 欧拉路
- SAP hybris企业级电商开发,Java程序员能做些什么?
- STL之string
- DFS Unique Binary Search Trees II