By Recognizing These Guys, We Find Social Networks Us第36届ACM国际大学生程序设计竞赛亚洲区预赛北京邀请赛bupt 197 tarjan+割边
来源:互联网 发布:session php 过期时间 编辑:程序博客网 时间:2024/04/30 04:17
/*题目地址:http://w.boj.me/onlinejudge/newoj/showProblem/show_problem.php?problem_id=197题意:给你一个人际关系网(双向的),让你求关键的关系,既如果这条关系断了,就会有某两个或以上的人失去联系了求这样的关系解法:tarjan算法 求割边dfn[v]记录到达点v 的时间,low[v]表示通过它的子结点可以到达的所有点中时间最小值,即low[i]=min(low[i],low[u]),u 为v 的了孙,初始化时low[v]=dfn[u]。如果low[v]比dfn[v]小,说明v 可以通过它的子结点u,u1,u2...到达它的祖先v',则存在环,这个环上所有的点组成的子图便是一个强连通分量。换一个角度看,如果当low[v]==dfn[v]时,则它的子树中所有low[u]==dfn[v]的点都与v 构成一个环,维护一个栈,DFS 过程中,每遍历一个点则把它放入栈中,当发现low[v]==dfn[v]则依次把栈里的元素都弹出来,当栈顶元素为v 时结束,这些点便构成一个以v 为树根的强连通分量。分析:如果low[u]>=dfn[v],说明v 的儿子u 不能通过其他边到达v 的祖先,此时如果拿掉v,则必定把v 的祖先和v 的儿子u,及它的子孙分开,于是v 便是一个割点,v 和它的子孙形成一个块。如果low[u]>dfn[v]时,则说明u 不仅不能到达v 的祖先,连v 也不能通过另外一条边直接到达,从而它们之间的边w(v,u)便是割边,*/#include<iostream>#include<cstdio>#include<cstring>#include<cmath>#include<algorithm>#include<queue>#include<vector>#include<stack>#include<map>using namespace std;//********************************************************************const int MAX=10009;const int MAXE=200009;int n,m;map<string,int> Map; //为字符串建立索引,既为每个人编号map<string,int> T; //string 为 人名1+" "+人名2 的关系,int为这个关系的出现次序string ans[10009]; //ans[i]表示第i个人的名字(字符串),使得从编号定位到人int ansnum; //ans的下标struct cmp//优先队列的比较,即在关系输入时顺序在前的排前面{bool operator()(const string s1,const string s2){return T[s1]>T[s2]; }};priority_queue<string,vector<string>,cmp> q;//为关系定义优先队列,为最后按顺序输出准备//***********************************************************************struct EDGE { int v; // 从u点出发能到达的点v int next; // 从u点出发能到达的下一条边的编号 }edge[MAXE]; int first[MAX]; // first[u] = e:从点u出发的最后一条边的编号是e(“最后”是指最后输入) int dfn[MAX]; // dfn[u]:节点u搜索的次序编号(时间戳) int low[MAX];// low[u]:是u或u的子树能够追溯到的最早的栈中节点的次序号 int endex; // 次序编号 int Stack[MAX];//栈int top;//栈顶指针int DFS(int x,int fa) //tarjan算法{ low[x]=dfn[x]=endex++; Stack[++top]=x; for(int k=first[x];k!=-1;k=edge[k].next) { int v=edge[k].v; if(v==fa)continue; if(dfn[v]==0) //时间戳为0,表示未访问过 { DFS(v,x); low[x]=min(low[x],low[v]);if(dfn[x]<low[v])//若x的子节点v无法追溯到x或x的祖先,那么x-v就是一条割边{string s=ans[x]+" "+ans[v];if(T[s]==0){q.push(ans[v]+" "+ans[x]);}else q.push(s); //将这条割边代表的关系放入优先队列中while(Stack[top]!=x){ top--; //沿栈找回x,途中的边必不是割边,注意x并为出栈}} } else{low[x]=min(low[x],dfn[v]);//有横向边时,更新最早时间} } return 1; } //**************************************************************************void solve(){Map.clear();T.clear();while(!q.empty()) q.pop(); memset(dfn,0,sizeof(dfn)); memset(low,0,sizeof(low)); memset(first,-1,sizeof(first)); scanf("%d%d",&n,&m); endex=1; ansnum=1;top=-1;int a,b;int Mnum=1; int e=0; string s1,s2;int tmp=0;for(int i=0;i<m;i++){cin>>s1>>s2;T[s1+" "+s2]=++tmp;// 为关系建立索引if(Map[s1]==0){Map[s1]=Mnum++;// 给人名编号ans[ansnum++]=s1;//建立编号定位人的机制}if(Map[s2]==0){Map[s2]=Mnum++;ans[ansnum++]=s2;}a=Map[s1];b=Map[s2];edge[e].v=b;edge[e].next=first[a];first[a]=e++;edge[e].v=a;edge[e].next=first[b];first[b]=e++;}DFS(1,1);if(q.empty()||endex<=n||n==1) cout<<"0"<<endl;//若endex<=n则图不全联通else{cout<<q.size()<<endl;while(!q.empty()){cout<<q.top()<<endl;q.pop();}}}//***********************************************************************int main(){int Case;scanf("%d",&Case);while(Case--){ solve();}return 0;}
- By Recognizing These Guys, We Find Social Networks Us第36届ACM国际大学生程序设计竞赛亚洲区预赛北京邀请赛bupt 197 tarjan+割边
- BUPT 网络预选赛邀请赛 B题 B By Recognizing These Guys, We Find Social Networks Useful
- HDU 3849 By Recognizing These Guys, We Find Social Networks Useful 找出所有割边
- hdu3849 By Recognizing These Guys, We Find Social Networks Useful
- HDU 3849 By Recognizing These Guys, We Find Social Networks Useful 边双连通
- HDU3849[By Recognizing These Guys, We Find Social Networks Useful ] tarjan求无向图的桥
- HDU 3849 Recognizing These Guys, We Find Social Networks Useful
- HDU 3849 By Recognizing These Guys, We Find Social Networks Useful
- hdu 3849 By Recognizing These Guys, We Find Social Networks Useful(双连通求桥)
- Hdu 3859 By Recognizing These Guys, We Find Social Networks Useful
- HDU 3849 By Recognizing These Guys, We Find Social Networks Useful 求桥及其节点
- hdu 3849 By Recognizing These Guys, We Find Social Networks Useful
- 【HDU】3849 By Recognizing These Guys, We Find Social Networks Useful 双连通求桥
- HDU 3849 By Recognizing These Guys, We Find Social Networks Useful(双连通)
- hdu 3849 By Recognizing These Guys, We Find Social Networks Useful
- HDU -- 3849 By Recognizing These Guys, We Find Social Networks Useful(双连通 求割边)
- hdoj 3849 By Recognizing These Guys, We Find Social Networks Useful 【无向图求桥】
- HDU - 3849 By Recognizing These Guys, We Find Social Networks Useful(桥)
- ZOJ1073 POJ1450 Gridland 投机取巧版。。。
- 排列组合算法
- MIT的EECS的课程所用到的书籍
- Tomcat+JSP经典配置
- 如何查看别人的siverlight源码
- By Recognizing These Guys, We Find Social Networks Us第36届ACM国际大学生程序设计竞赛亚洲区预赛北京邀请赛bupt 197 tarjan+割边
- XML DOM - The Element Object
- WPF学习笔记之资源基础详解
- android中sharedPreferences的用法详解
- (转)用Ubuntu破解wep无线加密
- 2011-7-17 blue screen
- jhost 邀请码
- XML DOM Get Node Values
- Log4j的简单运用