我的点双连通模板(HDU2242)
来源:互联网 发布:角平分线逆定理己知 编辑:程序博客网 时间:2024/05/10 10:23
http://acm.hdu.edu.cn/showproblem.php?pid=2242
const int Max_N = 10008 ;const int Max_M = 20008 ;struct Edge{ int u ; int v ; int next ;}edge[Max_M*4];int id ;int List[Max_N] , List2[Max_N] ;void add_edge(int u , int v ){ edge[id].u = u ; edge[id].v = v ; edge[id].next = List[u] ; List[u] = id++ ;}void add_edge2(int u , int v){ edge[id].u = u ; edge[id].v = v ; edge[id].next = List2[u] ; List2[u] = id++ ;}int val[Max_N] , sumall , sum[Max_N] , dp[Max_N] ;/*belong[u] , u所在的双连通分量 , color双连通分量个数 *//*同一个belong[]里的任意2点至少有2条不同的路径*/int dfsn[Max_N] , low[Max_N] , Time , color , belong[Max_N] ;stack <int> Q ;void tarjan(int u , int father){ int v , e , flag = 1 ; dfsn[u] = low[u] = ++Time ; Q.push(u) ; for(e = List[u] ; e != -1 ; e = edge[e].next){ v = edge[e].v ; if(v == father && flag){ //重边 flag = 0 ; continue ; } if(!dfsn[v]){ tarjan(v , u) ; low[u] = min(low[u] , low[v]) ; } else low[u] = min(low[u] ,dfsn[v]) ; } if(dfsn[u] == low[u]){ color++ ; do{ v = Q.top() ; Q.pop() ; belong[v] = color ; sum[color] += val[v] ; }while(u != v) ; }}int N , M ;void Init(){ id = color = sumall = Time = 0 ; memset(sum , 0 ,sizeof(sum)) ; memset(dfsn , 0 , sizeof(dfsn)) ; memset(List , -1 , sizeof(List)) ; memset(List2 , -1 , sizeof(List2)) ; memset(dp , 0 , sizeof(dp)) ;}int ans ;void dfs(int u , int father){ dp[u] = sum[u] ; int e , v ; for(e = List2[u] ; e != -1 ; e = edge[e].next){ v = edge[e].v ; if(v == father) continue ; dfs(v , u) ; dp[u] += dp[v] ; ans = min(ans , abs(sumall - 2 * dp[v])) ; }}int main(){ int i , u , v , e ; while(cin>>N>>M){ Init() ; for(i = 1 ; i <= N ; i++){ scanf("%d" ,&val[i]) ; sumall += val[i] ; } for(i = 1 ; i <= M ; i++){ scanf("%d%d" ,&u ,&v) ; u++ , v++ ; add_edge(u , v) ; add_edge(v , u) ; } for(i = 1 ; i <= N ; i++){ if(!dfsn[i]) tarjan(i , -1) ; } if(color == 1){ puts("impossible") ; continue ; } for(i = 1 ; i <= N ; i++){ for(e = List[i] ; e != -1 ; e = edge[e].next){ u = edge[e].u ; v = edge[e].v ; if(belong[u] != belong[v]) add_edge2(belong[u] , belong[v]) ; } } ans = 1<<30 ; dfs(1 , -1) ; cout<<ans<<endl ; } return 0 ;}
0 0
- 我的点双连通模板(HDU2242)
- hdu2242考研路茫茫——空调教室(边双连通,缩点,dfs)
- 我的 边双连通 模板
- 无向图的割点,割边,点双连通,边双连通模板
- 点-双连通分量模板
- 无向图的点双连通分量(tarjan模板)
- 无向图的双连通块(点的双连通)&&边的双连通算法
- 边双连通模板
- 点双连通 练习
- 【双连通】双连通模板 Tarjan
- hdu2242
- hdu 3749 点双连通
- hdu 3394(点双连通)
- POJ 2942 点双连通
- hdu 5739(点双连通)
- HDU 5739(点双连通)
- 双连通分量模板以及对一些不好理解点的解释
- POJ3352Road Construction(边的双连通+强连通缩点)
- C++模板编程->指针及引用模板参数
- ACM-简单题之{A} + {B}——hdu1412
- 统计句子中的小写字母的个数,并输出结果
- 12.4单选按钮
- vs2008 MSChart图表使用
- 我的点双连通模板(HDU2242)
- Android代码优化工具——Android lint
- 开源熔点工具箱~~
- 丈夫已将举报信寄至中纪委 当事区长被调查(图)
- 12.5ImageView的使用方法
- zju 1091
- NSSortDescriptor(数组排序)
- 12.6时间与日期
- 运行时常量池溢出