hdu4005The war tarjan缩点
来源:互联网 发布:c语言四大圣经 编辑:程序博客网 时间:2024/06/06 18:03
//给一个连通无向图,加上一条边需要删除一条边,使得这个图不连通//删除边需要花费钱,问最少需要准备多少钱使得不论加什么边最终都可以最终删除一条边使得原图不连通//所需要删的边一定是桥,所以先进行缩点使得其变为一棵树//在一棵树上加一条边后使得其有一个环,删除这个环的边后其依然连通//最坏的情况权值最小的边在这个环中,而且其必然是连接两个叶子节点,这样使得环覆盖的边尽量多//所以可以以权值最小的边将这棵树分为两棵,可以分别从这一最小边的两个端点为根节点出发//分别搜索这两棵树的经过其最小的边(不是上面的最小边)的路径,除了这个路径上的边以及这个最小边的端点为根的子树中所有的边//剩下的边的最小值即为答案#include<iostream>#include<cstdio>#include<cstring>#include<vector>using namespace std ;const int maxn = 200010 ;const int inf = 0x7fffffff ;int vis[maxn] ;int dfn[maxn] , low[maxn] ;int isstack[maxn] , stack[maxn] ,belong[maxn];int head[maxn] ; int n , m ;int nedge , num , step , top ;int ans ;struct Edge{ int u;int v ;int w ; int next ;}edge[maxn] ;vector<Edge> vec[maxn] ;void addedge(int u , int v , int w){ edge[nedge].v = v ; edge[nedge].w = w ; edge[nedge].next = head[u] ; head[u] = nedge++ ; edge[nedge].v = u ; edge[nedge].w = w ; edge[nedge].next = head[v] ; head[v] = nedge++ ;}void init(){ memset(dfn , 0 , sizeof(dfn)) ; memset(head , -1 ,sizeof(head)) ; memset(vis ,0 , sizeof(vis)) ; memset(isstack , 0 , sizeof(isstack)) ; for(int i = 0;i <= n;i++) vec[i].clear() ; nedge = num = step = top = 0 ;}void tarjan(int u){ stack[++top] = u ; isstack[u] = 1 ; low[u] = dfn[u] = ++step ; for(int i = head[u] ; i != -1 ;i = edge[i].next) { if(vis[i])continue ; vis[i] = vis[i^1] = 1 ; int v = edge[i].v ; if(!dfn[v]) { tarjan(v) ; low[u] = min(low[u] , low[v]) ; } else if(isstack[v]) low[u] = min(low[u] , dfn[v]) ; } if(low[u] == dfn[u]) { num++ ; int v = 0; while(v!=u) { v = stack[top--] ; isstack[v] = 0 ; belong[v] = num ; } }}Edge build_tree(){ Edge tmp ;tmp.w = inf ; for(int i = 1;i <= n;i++) for(int j = head[i] ; j != -1 ;j = edge[j].next) { int u = belong[i] ; int v = belong[edge[j].v] ; if(u == v)continue ; Edge newedge = {u , v , edge[j].w,0} ; if(edge[j].w < tmp.w) { tmp.w = edge[j].w ; tmp.u = u ; tmp.v = v ; } vec[u].push_back(newedge); } return tmp ;}int dfs(int u , int pre){ int mi_f = inf, mi_s = inf; for(int i = 0;i < vec[u].size() ;i++) { int v = vec[u][i].v ; if(v == pre)continue ; int sum = min(vec[u][i].w , dfs(v , u)) ; if(sum <= mi_f) { mi_s = mi_f ; mi_f = sum ; } else mi_s = min(mi_s , sum) ; } ans = min(ans , mi_s) ; return mi_f ;}void debug(){ for(int i = 1;i <= num;i++) for(int j = 0;j < vec[i].size();j++) printf("%d %d %d\n" , i , vec[i][j].v , vec[i][j].w) ;}int main(){ //freopen("in.txt" , "r" , stdin) ; while(~scanf("%d%d" , &n , &m)) { int u , v , w ; init() ; while(m--) { scanf("%d%d%d" , &u ,&v ,&w) ; addedge(u , v , w) ; } tarjan(1) ; Edge tmp = build_tree() ; ans = inf ; if(num == 1) { puts("-1"); continue ; } dfs(tmp.u , tmp.v) ; dfs(tmp.v , tmp.u) ; if(ans == inf)puts("-1") ; else cout<<ans<<endl; }}
0 0
- hdu4005The war tarjan缩点
- hdu4005The war
- hdu4005The war
- POJ 3114 Countries in War 最短路+tarjan缩点
- poj1904 tarjan缩点
- HDU3836 Tarjan缩点
- HDU3836(tarjan+缩点)
- 1827 tarjan+缩点
- tarjan+缩点
- tarjan + 缩点
- Tarjan缩点
- POJ1236----tarjan缩点
- tarjan+缩点
- hdu5934 Tarjan 缩点
- poj2186--tarjan+缩点
- hdu5934(tarjan缩点)
- Tarjan缩点模板
- 图论--tarjan缩点
- 学习笔记——ajax传值数组对象中遇到的问题
- DAY_18_linux/list.h
- KEIL Memory Model
- OS-2
- UI08_UITableView界面传值(后往前)
- hdu4005The war tarjan缩点
- OS-3
- J2EE基础Servlet
- OS-4
- HDU 4123 Bob’s Race(树形DP + 单调队列)
- hdoj 2102 A计划 【BFS】
- 2015-我的蓝桥之旅
- 从概念及汇编角度解释指针本质
- OpenID及其原理介绍