您的位置:首页 > 其它

ZOJ2588 Burning Bridges

2016-05-05 20:23 267 查看
一.原题链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=1588

二.题目大意:给你一个图,让你求出每一条割边。

三.思路:Tarjan求割边,注意判断有没有重边,意味着要标记,而且数据量太大要用邻接表。判断重边我采用遍历的方法,然后就是传统的对于一个节点u,如果存在一个深度优先搜索树的儿子v使得low[v]>dfn[u],则边(u,v)为割边。注意在求割点的时候是low[v]>=dfn[u],这时重边也都没有关系,等号的成立的情况其实就是重边使得回边从v->u,但是割边的话重边一定就不能是割边了,虽然我把重边先全部去除了。

Tarjan算法详情:http://blog.csdn.net/h992109898/article/details/51318135

吐槽一下:没见过这么恶心的输出格式控制,末尾空格,最后一个样例的空格都卡。

四.代码:

#include <iostream>
#include <cstdio>
#include <queue>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <vector>

using namespace std;

const int MAX_N = 10005,
INF = 0x3f3f3f3f;

struct Edge
{
int u, v, id;
bool isRepeat;
};

vector <Edge> edges[MAX_N];
vector <Edge> res;
int edgeNum, nodeNum, head[MAX_N],
low[MAX_N], dfn[MAX_N];
bool visited[MAX_N];

void init()
{
int i;
memset(visited, 0, sizeof(visited));
for(i = 0; i < MAX_N; i++)
edges[i].clear();
res.clear();
}

void addEdge(int u, int v, int id)
{
int i;
Edge tmp;
tmp.u = u, tmp.v = v, tmp.id = id;
tmp.isRepeat = false;
//判重边
for(i = 0; i < edges[u].size(); i++)
if(v == edges[u][i].v){
edges[u][i].isRepeat = true;
return;
}
edges[u].push_back(tmp);
}

void dfs(int pre, int u, int depth)
{
visited[u] = true;
low[u] = dfn[u] = depth;
int i, v;
for(i = 0; i < edges[u].size(); i++){
v = edges[u][i].v;
if(!visited[v]){
dfs(u, v, depth + 1);
low[u] = min(low[u], low[v]);
if(low[v] > dfn[u] && !edges[u][i].isRepeat){
res.push_back(edges[u][i]);
}
}
else if(v != pre)
low[u] = min(low[u], dfn[v]);
}
}

bool cmp(Edge a, Edge b)
{
return a.id < b.id;
}

int main()
{
//freopen("in.txt", "r", stdin);

int test, u, v, i;

scanf("%d", &test);

while(test--){
init();
scanf("%d%d", &nodeNum, &edgeNum);

for(i = 0; i < edgeNum; i++){
scanf("%d%d", &u, &v);
addEdge(u, v, i + 1);
addEdge(v, u, i + 1);
}

dfs(1, 1, 1);

int num = res.size();
sort(res.begin(), res.end(), cmp);
printf("%d\n", num);

if(num){
printf("%d", res[0].id);
for(i = 1; i < num; i++)
printf(" %d", res[i].id);
printf("\n");
}
if(test)
printf("\n");
}

return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: