UVA 315 求割点数

来源:互联网 发布:八上数学行知天下答案 编辑:程序博客网 时间:2024/05/16 07:33

题目链接:http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=251

测模版:

#include <stdio.h>#include <iostream>#include <algorithm>#include <string.h>#include <queue>#include <vector>using namespace std;#define N 100005#define M 200300#define inf 10000000struct Edge{int from,to,next;bool cut;}edge[2*M];int head[N],edgenum;int Low[N],DFN[N],Stack[N],Stack2[N];//Belong数组的值是1~blockint Index,top,top2;int Belong[N],block;//新图的连通块标号(1~block)bool Instack[N], cut[N];int bridge; //割桥数量int add_block[N]; //add_block[i]表示删掉i点后增加的连通分量数void addedge(int u,int v){Edge E={u,v,head[u],0}; edge[edgenum]=E; head[u] = edgenum++;Edge E2={v,u,head[v],0};edge[edgenum]=E2;head[v] = edgenum++;}void Tarjan(int u,int pre){int v, son = 0;Low[u] = DFN[u] = ++Index;Stack[top++] = u;Stack2[top2++] = u;Instack[u] = true;for(int i = head[u]; ~i ;i = edge[i].next){v = edge[i].to;// 如果重边有效的话下面这句改成: if(v == pre && pre_num == 0){pre_num++;continue;} pre_num在for上面定义 int pre_num=0;if( v == pre )continue;if( !DFN[v] ){son++;Tarjan(v,u);if(Low[u] > Low[v])Low[u] = Low[v];if(Low[v] > Low[u]){bridge++;edge[i].cut = edge[i^1].cut = true;}if(u != pre && Low[v] >= DFN[u])//不是树根{cut[u] = true;add_block[u]++;}}else if(Low[u] > DFN[v])Low[u] = DFN[v];}if(Low[u] == DFN[u]){block++;do{v = Stack[--top];Instack[v] = false;Belong[v] = block;}while( v != u );}if(u == pre && son > 1)cut[u] = true;if(u == pre)add_block[u] = son - 1;Instack[u] = false;top2--;}void work(int l, int r){memset(DFN,0,sizeof(DFN));memset(Instack,false,sizeof(Instack));memset(cut, false, sizeof cut);Index = top = block = bridge = 0;top2 = 0;for(int i = l; i <= r; i++)if(!DFN[i])Tarjan(i,i);}vector<int>G[N];//点标从1-blockvoid suodian(){for(int i = 1; i <= block; i++)G[i].clear();for(int i = 0; i < edgenum; i+=2){int u = Belong[edge[i].from], v = Belong[edge[i].to];if(u==v)continue;G[u].push_back(v), G[v].push_back(u);}}void init(){edgenum = 0; memset(head,-1,sizeof(head));}int g[110][110];char buf[1010];int main(){int n;while(scanf("%d",&n),n){gets(buf);memset(g,0,sizeof(g));while(gets(buf)){if(strcmp(buf,"0")==0)break;char *p = strtok(buf," ");int u;sscanf(p,"%d",&u);p = strtok(NULL," ");int v;while(p){sscanf(p,"%d",&v);p = strtok(NULL," ");g[u][v]=g[v][u]=1;}}init();for(int i = 1;i <= n;i++)for(int j = i+1;j <= n;j++)if(g[i][j]){addedge(i,j);}work(1,n);int ans = 0;for(int i = 1; i <= n; i++)ans += cut[i];printf("%d\n",ans);}return 0;}


0 0
原创粉丝点击