点连通分量
来源:互联网 发布:人工智能豆瓣 编辑:程序博客网 时间:2024/05/21 19:24
[Submit] [Go Back] [Status]
Description
Gymman vs Fila
The great king Gymman and his queen Asira were living together happily. But an evil magician the evil Fila, who is trying to get hold of the throne had made a plan to separate the king and queen to get hold of the throne.
There were many cities in the kingdom. All of them were connected with bidirectional roads. He planned to send the king and queen into two different cities giving wrong messages, as without the queen, king would be very sad and unable to continue ruling. The evil fila succeeded on his task, as king and queen are not evil and they believed him. Though now king and queen lives in different city they frequently communicate with each other. The communication took place through letters and to exchange letters in kingdom the two corresponding cities should be connected through one or more bidirectional roads.
After the separation of king and queen, a natural calamity came into the kingdom and destroyed some of the bidirectional roads. If the king and queen still can communicate with each other Fila have to block communication between them. But he can occupy only one city and siege the letter carrier. King got this information of the evil plan.
Now he wants to know according to Fila's plan how many different combination of 3 citiesa, b, c ( abc) exists such that king will be on city a, queen will be on cityb and evil Fila will be on city c and Fila can block communication between king and queen. Two combinations (x1, y1, z1) and (x2, y2, z2) will be same ifx1 and x2 are same,y1 and y2 are same andz1 and z2 are same. As Fila is an evil magician, he can go to any city with his magical power without the help of road transports.
Input
First line contains T ( 1 < T < 21), the number of test cases to follow.
For each test case, in the 1st line there will be 2 integers N ( 1N20000) and M ( 0M100000).N is the number of cities and M is the number of roads between them.
M lines follow, each containing two integersu and v. That means there is a bidirectional road between cityu and city v. The cities are numbered from 1 toN. All roads will be distinct and connect two different cities.
Output
For each case, print the test case number starting from 1 and the number of combinations in one line. See sample output for exact formatting.
Explanation:
In 2-nd test case, 4 triplets are (1, 2, 3), (1, 4, 3), (2, 1, 3) and (4, 1, 3).
In 3-rd test case, 2 triplets are (4, 6, 5) and (6, 4, 5).
Sample Input
33 31 22 31 34 42 44 32 33 16 51 22 31 34 55 6
Sample Output
Case 1: 0Case 2: 4Case 3: 2
求有多少对这种组合,[x,y,z],去掉点y,那么x,y就断开,双连通缩点,然后枚举割点,新学习别人的建图方法。
代码:
/* ***********************************************Author :rabbitCreated Time :2014/4/15 15:58:56File Name :F.cpp************************************************ */#pragma comment(linker, "/STACK:102400000,102400000")#include <stdio.h>#include <iostream>#include <algorithm>#include <sstream>#include <stdlib.h>#include <string.h>#include <limits.h>#include <string>#include <time.h>#include <math.h>#include <queue>#include <stack>#include <set>#include <map>using namespace std;#define INF 0x3f3f3f3f#define eps 1e-8#define pi acos(-1.0)typedef long long ll;const int maxn=100100;int head[maxn],tol;int low[maxn],dfn[maxn],indexx,cut[maxn],block,st[maxn],top;int n,m;vector<int> node[maxn],com[maxn],G[maxn];int cnt[maxn];struct Edge{int from,to,vis,next;Edge(int _from=0,int _to=0,int _vis=0,int _next=0){from=_from;to=_to;vis=_vis,next=_next;}}edge[5*maxn];void addedge(int u,int v,int vis){edge[tol]=Edge(u,v,vis,head[u]);head[u]=tol++;}void tarjan(int u,int pre){low[u]=dfn[u]=++indexx;int son=0;for(int i=head[u];i!=-1;i=edge[i].next){if(edge[i].vis)continue;st[top++]=i;edge[i].vis=edge[i^1].vis=1;int v=edge[i].to;if(!dfn[v]){tarjan(v,u);son++;low[u]=min(low[u],low[v]);if(low[v]>=dfn[u]){if(u!=pre)cut[u]=1;++block;int s,t,k;com[block].clear();do{k=st[--top];s=edge[k].from;t=edge[k].to;com[block].push_back(s);com[block].push_back(t);node[s].push_back(block);node[t].push_back(block);}while(s!=u);}}else low[u]=min(low[u],dfn[v]);}if(u==pre&&son>1)cut[u]=1;}void bcc(int n){indexx=top=block=0;memset(dfn,0,sizeof(dfn));memset(cut,0,sizeof(cut));for(int i=1;i<=n;i++)node[i].clear();for(int i=1;i<=n;i++)if(!dfn[i])tarjan(i,i);for(int i=1;i<=n+block;i++)G[i].clear();for(int i=1;i<=n;i++)if(cut[i]){sort(node[i].begin(),node[i].end());node[i].resize(unique(node[i].begin(),node[i].end())-node[i].begin());for(int j=0;j<node[i].size();j++){int x=i,y=node[i][j]+n;G[x].push_back(y);G[y].push_back(x);}}}ll ans,cur,dp[maxn];bool vis[maxn],mark[maxn];void find(int u){cur+=cnt[u];mark[u]=1;for(int i=0;i<G[u].size();i++){int v=G[u][i];if(!mark[v])find(v);}}void dfs(int u){dp[u]=0;vis[u]=1;for(int i=0;i<G[u].size();i++){int v=G[u][i];if(vis[v])continue;dfs(v);if(cut[u])ans+=dp[u]*dp[v];dp[u]+=dp[v];}dp[u]+=cnt[u];if(cut[u])ans+=(dp[u]-1)*(cur-dp[u]);}int main(){ //freopen("data.in","r",stdin); //freopen("data.out","w",stdout); int T,t; scanf("%d",&T); for(int t=1;t<=T;t++){ memset(head,-1,sizeof(head));tol=0; scanf("%d%d",&n,&m); while(m--){ int x,y;scanf("%d%d",&x,&y); addedge(x,y,0); addedge(y,x,0); } bcc(n);// cout<<"block="<<block<<endl; memset(cnt,0,sizeof(cnt)); for(int i=1;i<=n;i++)if(cut[i])cnt[i]=1; for(int i=1;i<=block;i++){ sort(com[i].begin(),com[i].end()); com[i].resize(unique(com[i].begin(),com[i].end())-com[i].begin()); for(int j=0;j<com[i].size();j++)if(!cut[com[i][j]])cnt[i+n]++; } memset(vis,0,sizeof(vis)); ans=0; for(int i=1;i<=n+block;i++)if(!vis[i]){ memset(mark,0,sizeof(bool)*(n+block+100)); cur=0; find(i); dfs(i); } printf("Case %d: %lld\n", t, ans<<1); } return 0;}
- 点连通分量
- poj1523 割点+连通分量
- 强连通分量缩点
- 强连通分量缩点
- 点连通分量+边连通分量+割点和桥+强连通分量
- 强连通分量 + 缩点 kosaraju
- 强连通分量缩点的模板
- POJ2186 Tarjan强连通分量+缩点
- 强连通分量+缩点-poj1236
- 强连通分量+缩点uva12167
- poj 2186 强连通分量 缩点
- poj 1236 强连通分量 缩点
- 强连通分量+缩点(poj2553)
- poj1236强连通分量+缩点
- 强连通分量(割点)
- hdu 4635 强连通分量+缩点
- POJ2186Popular Cows(强连通分量+缩点)
- poj 1236 强连通分量+缩点
- java中static的作用
- 选择排序算法中的交换数值问题
- c++ primer阅读笔记-15章-2
- 微软面试100题之20题:输入一个表示整数的字符串,把该字符串转换成整数并输出
- sort函数
- 点连通分量
- 不得不说的故事:STL内存管理
- 安装sql2005,没有SQL Server management studio的原因分析及解决方案
- 怎样校验MD5码及sha1码数值(适用于Windows及Linux平台)
- 手把手教你使用TI MSP430 LaunchPad
- codeblocks搭建opencv环境完美教程
- 总结一下自己的实训经历吧
- unicode与utf-8互转
- List陷阱 写过一次很蠢的代码