zoukankan      html  css  js  c++  java
  • hdu 2242(边双连通分量)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2242

    思路:Tarjan求边双连通分量,进行缩点后成树,然后就是树型dp,求一下最小差值就行了。

    ps:注意点:由于双向建边,DP搜索时要记录父亲,只能往下搜,不能搜该节点的父亲。

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<algorithm>
     5 #include<stack>
     6 #include<vector>
     7 using namespace std;
     8 #define MAXN 10000+10
     9 #define inf 1<<30
    10 stack<int>S;
    11 vector<int>vet[MAXN];
    12 vector<int>map[MAXN];
    13 int n,m,cnt,_count,sum,MIN;
    14 int dfn[MAXN],low[MAXN];
    15 bool mark[MAXN];
    16 int color[MAXN];
    17 int dp[MAXN];
    18 int value[MAXN];
    19 
    20 //tarjan算法找边双联通分量并进行缩点
    21 void Tarjan(int u,int father){
    22    int flag=0;
    23    dfn[u]=low[u]=++cnt;
    24    mark[u]=true;
    25    S.push(u);
    26    for(int i=0;i<vet[u].size();i++){
    27       int v=vet[u][i];
    28       if(v==father&&!flag){ flag=1;continue; }//考虑重边情况,重要
    29       if(!mark[v])Tarjan(v,u);
    30       low[u]=min(low[u],low[v]);
    31    }
    32    if(low[u]==dfn[u]){
    33       _count++;
    34       int v;
    35       do{
    36          v=S.top();
    37          S.pop();
    38          color[v]=_count;//染色
    39          dp[_count]+=value[v];//求缩点后的价值
    40       }while(u!=v);
    41    }
    42 }
    43 
    44 //树型dp求最小差值
    45 int dfs(int u,int father){
    46    int ans=dp[u];
    47    for(int i=0;i<map[u].size();i++){
    48       int v=map[u][i];
    49       if(v==father)continue;
    50       ans+=dfs(v,u);
    51    }
    52    MIN=min(MIN,abs((sum-ans)-ans));
    53    return ans;
    54 }
    55 
    56 
    57 
    58 int main(){
    59 //   freopen("1.txt","r",stdin);
    60    int u,v;
    61    while(~scanf("%d%d",&n,&m)){
    62       sum=cnt=_count=0;MIN=inf;
    63       for(int i=0;i<=n;i++){ vet[i].clear();map[i].clear(); }
    64       for(int i=0;i<n;i++){ scanf("%d",&value[i]);sum+=value[i]; }
    65       while(m--){
    66          scanf("%d%d",&u,&v);
    67          vet[u].push_back(v);
    68          vet[v].push_back(u);
    69       }
    70       memset(color,0,sizeof(color));
    71       memset(dfn,0,sizeof(dfn));
    72       memset(low,0,sizeof(low));
    73       memset(mark,false,sizeof(mark));
    74       memset(dp,0,sizeof(dp));
    75       Tarjan(0,0);
    76       if(_count==1){ puts("impossible");continue; }
    77       for(int i=0;i<n;i++){
    78          for(int j=0;j<vet[i].size();j++){
    79             if(color[i]!=color[vet[i][j]]){
    80                map[color[i]].push_back(color[vet[i][j]]);
    81             }
    82          }
    83       }
    84       dfs(1,0);
    85       printf("%d\n",MIN);
    86    }
    87    return 0;
    88 }
    View Code
  • 相关阅读:
    mysql数据库表中判断字段是否存在,如果不存在则创建该字段
    PHP同时操作两个mysql数据库
    Bootstrap-分页插件Paginator
    NLP--自然语言处理与机器学习会议
    对CURL的一些研究
    Nginx完整配置说明
    SecureCRT自动登陆到服务器的脚本以及脚本编写简单说明
    Fast CGI 工作原理
    FastCGI中文规范
    Linux +apache+fastcgi运行c/c++
  • 原文地址:https://www.cnblogs.com/wally/p/3117913.html
Copyright © 2011-2022 走看看