zoukankan      html  css  js  c++  java
  • hdu2242(树形dp+tarjan+缩点)

    hdu2242 http://acm.hdu.edu.cn/showproblem.php?pid=2242

    给定n,m表示n个点,m条边

    每个点有个权值

    问我们删除两某条边(割边)后将图分为两个部分,要使得两个部分的权值之差最小

    这题的弱化版本是在一棵树上删除某条边后后将图分为两个部分,要使得两个部分的权值之差最小。是用树形dp来做的

    但是这道题目是个图,但是我们可以转化为树,即将图中的边连通分量求出来,然后缩成一个点,建出一个新的树图,那么就可以用树形dp来求解题目了.

      1 #include <stdio.h>
      2 #include <string.h>
      3 #include <stdlib.h>
      4 #include <algorithm>
      5 #include <iostream>
      6 #include <queue>
      7 #include <stack>
      8 #include <vector>
      9 #include <map>
     10 #include <set>
     11 #include <string>
     12 #include <math.h>
     13 using namespace std;
     14 typedef long long LL;                   
     15 const int INF = 1<<30;
     16 const int N = 10000 + 10;
     17 vector<int> g1[N],g2[N];
     18 int val1[N],val2[N];
     19 int dfn[N],low[N],dfs_clock,cnt;
     20 int belong[N];
     21 stack<int> st;
     22 bool vis[N];
     23 int ans,sum;
     24 void tarjan(int u, int fa)
     25 {
     26     bool flag = false;
     27     vis[u] = true;
     28     dfn[u] = low[u] = ++dfs_clock;
     29     st.push(u);
     30     for(int i=0; i<g1[u].size(); ++i)
     31     {
     32         
     33         int v = g1[u][i];
     34         if(v==fa && !flag) 
     35         {
     36             flag = true;
     37             continue;
     38         }
     39         if(!vis[v]) tarjan(v,u);
     40         low[u] = min(low[u],low[v]);
     41     }
     42     if(dfn[u]==low[u])
     43     {
     44         cnt++;
     45         int x;
     46         do
     47         {
     48             x= st.top();
     49             st.pop();
     50             belong[x] = cnt;
     51             val2[cnt] += val1[x];
     52         }while(u!=x);
     53     }
     54 }
     55 
     56 void dfs(int u, int fa)
     57 {
     58     vis[u] = true;
     59     for(int i=0; i<g2[u].size(); ++i)
     60     {
     61         int v = g2[u][i];
     62         if(vis[v]) continue;
     63         dfs(v,u);
     64         val2[u] += val2[v];
     65     }
     66 }
     67 void dfs2(int u, int fa)
     68 {
     69     vis[u] = true;
     70     for(int i=0; i<g2[u].size(); ++i)
     71     {
     72         int v = g2[u][i];
     73         if(vis[v]) continue;
     74         ans = min(ans,abs(sum-2*val2[v]));
     75         dfs2(v,u);
     76     }
     77 }
     78 int main()
     79 {
     80     int n,m,i,u,v,j;
     81     while(scanf("%d%d",&n,&m)!=EOF)
     82     {
     83         for(i=0; i<=n; ++i)
     84         {
     85             g1[i].clear();
     86             g2[i].clear();
     87         }
     88         sum = 0;
     89         for(i=0; i<n; ++i)
     90         {
     91             scanf("%d",&val1[i]);
     92             sum += val1[i];
     93         }    
     94         for(i=0; i<m; ++i)
     95         {
     96             scanf("%d%d",&u,&v);
     97             g1[u].push_back(v);
     98             g1[v].push_back(u);
     99         }
    100         memset(vis,0,sizeof(vis));
    101         memset(dfn,0,sizeof(dfn));
    102         memset(low,0,sizeof(low));
    103         memset(val2,0,sizeof(val2));
    104         dfs_clock = 0;
    105         cnt = 0;
    106         tarjan(0,-1);
    107         for(i=0; i<n; ++i)
    108             for(j=0; j<g1[i].size(); ++j)
    109             {
    110                 int v = g1[i][j];
    111                 if(belong[v] != belong[i])//建新图,虽然新建的图会有重边,但是不影响树形dp
    112                 {
    113                     g2[belong[i]].push_back(belong[v]);
    114                     g2[belong[v]].push_back(belong[i]);
    115                 }
    116             }
    117         if(cnt==1)//如果整个图是边连通的,那么不管删哪条边都不能使得图不连通
    118         {
    119             puts("impossible");
    120             continue;
    121         }    
    122         ans = INF;
    123         memset(vis,0,sizeof(vis));
    124         dfs(1,-1);
    125         memset(vis,0,sizeof(vis));
    126         dfs2(1,-1);
    127         printf("%d
    ",ans);
    128     }
    129     return 0;
    130 }
    View Code
  • 相关阅读:
    SETI ACdream
    字符串野指针 百练2681
    mvc架构的简单登录系统,jsp
    servlet修改后无效,仍然还是修改之前的效果
    mysql安装,数据库连接
    the process android.process.acore has stopped或the process com.phone。。。。
    软件测试
    vim实用技巧
    ubuntu终端白屏的解决方法
    vim相关资料
  • 原文地址:https://www.cnblogs.com/justPassBy/p/4442356.html
Copyright © 2011-2022 走看看