ACdream 1236 Burning Bridges 割边 + 去重边
2016-09-19 19:39
344 查看
题目就是求一副图的割边,然后对于那些有重复的边的,不能算做割边。
思路就是每次加入一条边的时候,判断这条边是否存在过,存在过的话,就把那条边设为inf,表示不能作为割边。于是有了这样的代码
View Code
思路就是每次加入一条边的时候,判断这条边是否存在过,存在过的话,就把那条边设为inf,表示不能作为割边。于是有了这样的代码
#include <cstdio> #include <cstdlib> #include <cstring> #include <cmath> #include <algorithm> using namespace std; #define inf (0x3f3f3f3f) typedef long long int LL; #include <iostream> #include <sstream> #include <vector> #include <set> #include <map> #include <queue> #include <string> const int maxn=100000+20; struct data { int u,v,id; int next; } e[maxn*2]; int first[10000+20]; int num;//用到第几条边 bool isok (int u,int v) { //问一下u顶点所有边能不能去这个点 for (int i=first[u]; i; i=e[i].next) { if (e[i].v==v) { e[i].id=inf; return false; } } return true; } void add (int u,int v,int id) { // if (!isok(u,v)) return ;//判断是否有重复的边,绝对不是桥 ++num; e[num].u=u; e[num].v=v; e[num].id=id; e[num].next=first[u]; first[u]=num; return ; } int DFN[10000+20];//第几个被访问到 int low[10000+20];//最厉害能访问到谁 int used[10000 + 20]; int togo[10000 + 20]; int when;//什么时候被访问到的 int root; set<int>pr; void dfs (int cur,int father) { ++when; DFN[cur]=when; low[cur]=when; for (int i=first[cur]; i; i=e[i].next) { int v=e[i].v;//cur是爸爸,v是儿子 if (!DFN[v]) { //没访问过的话 dfs(v,cur); low[cur]=min(low[cur],low[v]); if (low[v]>DFN[cur]&&e[i].id!=inf) { pr.insert(e[i].id); } } else if(v!=father) { low[cur]=min(low[cur],DFN[v]); } } return ; } void init () { memset(togo, 0, sizeof togo); memset(used, 0, sizeof used); pr.clear(); memset(DFN,0,sizeof(DFN)); memset(low,0,sizeof(low)); memset (first,0,sizeof first); when=0; num=0; return ; } int n,m; void work () { init (); for (int i=1; i<=m; i++) { int u,v; scanf ("%d%d",&u,&v); add(u,v,i); add(v,u,i); } for (int i = 1; i <= n; ++i) { // memset(used, 0, sizeof used); for (int j = first[i]; j; j = e[j].next) { if (used[e[j].v] == e[j].u) { e[j].id = inf; e[togo[e[j].v]].id = inf; } used[e[j].v] = e[j].u; togo[e[j].v] = j; } } root=1;//从根节点 dfs(1,root); printf ("%d\n",pr.size()); for (set<int>::iterator it= pr.begin(); it!=pr.end(); ++it) { printf ("%d ",*it); } printf ("\n"); return ; } int main () { #ifdef local freopen("data.txt", "r", stdin); #endif while (scanf ("%d%d",&n,&m)!=EOF) work (); return 0; }
View Code
相关文章推荐
- Android自定义控件之百分比圆环进度条
- 页标题用SpringMVC 3和tiles2本土化
- 数据库编程(简易)
- 【HDU 5895】【指数循环节 矩阵 快速幂 逆元 推公式】Mathematician QSC 由递推式推公式
- 【算法】给定能随机生成整数1到5的函数,写出能随机生成整数1到7的函数
- 学生会竞选发言稿
- go与java互用的AES实现
- bold, big, blink
- 前端框架Avalon:简介
- Leetcode 63 Unique Paths II
- iptables基础概念
- iptables基础概念
- 虚拟内存和虚拟地址
- Unix网络编程之select版客户端实现
- Toast总结一
- RSA、DES 、AES、MD5加密、解密
- Python for Data Analysis (8)
- BOM学习笔记----------(一)
- 学 Win32 汇编[28] - 跳转指令: JMP、JECXZ、JA、JB、JG、JL、JE、JZ、JS、JC、JO、JP 等
- C++ Notes-Inheritance-01