zoukankan      html  css  js  c++  java
  • 51nod1325 两棵树的问题

    $n leq 50$的两棵树,同编号的点有同个点权,问如何选一个点集,使得这个点集里的点在两棵树内都连通,且总点权最大,输出最大点权和。

    枚举一个点在答案里,然后把树以它为根,此时选儿子一定要选父亲,构成最大权闭合子图。

      1 #include<iostream>
      2 #include<cstring>
      3 #include<cstdio>
      4 //#include<time.h>
      5 //#include<complex>
      6 //#include<set>
      7 //#include<queue>
      8 #include<algorithm>
      9 #include<stdlib.h>
     10 using namespace std;
     11 
     12 #define LL long long
     13 int qread()
     14 {
     15     char c; int s=0,f=1; while ((c=getchar())<'0' || c>'9') (c=='-') && (f=-1);
     16     do s=s*10+c-'0'; while ((c=getchar())>='0' && c<='9'); return s*f;
     17 }
     18 
     19 //Pay attention to '-' , LL and double of qread!!!!
     20 
     21 int n,m;
     22 #define maxn 111
     23 #define maxm 1111
     24 struct Edge{int to,next,flow,cap;};
     25 struct Network
     26 {
     27     Edge edge[maxm]; int first[maxn],le,n;
     28     void clear(int N) {le=2; memset(first,0,sizeof(first)); n=N;}
     29     void in(int x,int y,int cap) {Edge &e=edge[le]; e.to=y; e.cap=cap; e.flow=0; e.next=first[x]; first[x]=le++;}
     30     void insert(int x,int y,int cap) {in(x,y,cap); in(y,x,0);}
     31     int dis[maxn]; int que[maxn],cur[maxn],head,tail,s,t;
     32     bool bfs()
     33     {
     34         memset(dis,0,sizeof(dis)); dis[s]=1;
     35         head=tail=0; que[tail++]=s;
     36         while (head!=tail)
     37         {
     38             int x=que[head++];
     39             for (int i=first[x];i;i=edge[i].next)
     40             {
     41                 Edge &e=edge[i];
     42                 if (!dis[e.to] && e.cap>e.flow)
     43                 {
     44                     dis[e.to]=dis[x]+1;
     45                     que[tail++]=e.to;
     46                 }
     47             }
     48         }
     49         return dis[t];
     50     }
     51     int dfs(int x,int a)
     52     {
     53         if (x==t || !a) return a;
     54         int flow=0,f;
     55         for (int &i=cur[x];i;i=edge[i].next)
     56         {
     57             Edge &e=edge[i];
     58             if (dis[e.to]==dis[x]+1 && (f=dfs(e.to,min(e.cap-e.flow,a)))>0)
     59             {
     60                 flow+=f; e.flow+=f;
     61                 edge[i^1].flow-=f; a-=f;
     62                 if (!a) break;
     63             }
     64         }
     65         return flow;
     66     }
     67     int Dinic(int S,int T)
     68     {
     69         s=S; t=T;
     70         int ans=0;
     71         while (bfs())
     72         {
     73             for (int i=1;i<=n;i++) cur[i]=first[i];
     74             ans+=dfs(s,0x3f3f3f3f);
     75         }
     76         return ans;
     77     }
     78     bool vis[maxn];
     79     void dfs(int x)
     80     {
     81         vis[x]=1;
     82         for (int i=first[x];i;i=edge[i].next)
     83         {
     84             Edge &e=edge[i];
     85             if (e.cap>e.flow && !vis[e.to]) dfs(e.to);
     86         }
     87     }
     88 }g;
     89 
     90 struct EE{int to,next;};
     91 struct Tree
     92 {
     93     EE edge[maxn<<1]; int first[maxn],le;
     94     Tree() {le=2;}
     95     void in(int x,int y) {EE &e=edge[le]; e.to=y; e.next=first[x]; first[x]=le++;}
     96     void insert(int x,int y) {in(x,y); in(y,x);}
     97 }t[2];
     98 
     99 int ss[maxn];
    100 void dfs(int p,int x,int fa)
    101 {
    102     for (int i=t[p].first[x];i;i=t[p].edge[i].next)
    103     {
    104         EE &e=t[p].edge[i]; if (e.to==fa) continue;
    105         g.insert(e.to,x,0x3f3f3f3f); dfs(p,e.to,x);
    106     }
    107 }
    108 
    109 int main()
    110 {
    111     n=qread(); int sum=0;
    112     for (int i=1;i<=n;i++) {ss[i]=qread(); if (ss[i]>0) sum+=ss[i];}
    113     for (int i=1;i<n;i++) t[0].insert(qread()+1,qread()+1);
    114     for (int i=1;i<n;i++) t[1].insert(qread()+1,qread()+1);
    115     int s=n+1,t=s+1;
    116     int ans=0;
    117     for (int i=1;i<=n;i++)
    118     {
    119         g.clear(t);
    120         dfs(0,i,0); dfs(1,i,0);
    121         for (int j=1;j<=n;j++) if (ss[j]>0) g.insert(s,j,ss[j]);
    122         else g.insert(j,t,-ss[j]);
    123         ans=max(ans,sum-g.Dinic(s,t));
    124     }
    125     printf("%d
    ",ans);
    126     return 0;
    127 }
    View Code
  • 相关阅读:
    Linux命令总结--grep命令
    Linux命令总结--sed命令
    python函数--enumerate()方法
    python函数--index()方法
    在objc项目中使用常量的最佳实践
    iOS 开发 初级:应用内购买 In-App Purchase
    CFUUIDRef和CFStringRef-生成唯一标识符
    保留你的dSYM文件
    xcode 环境,多工程联编设置【转】
    ld: symbol dyld_stub_binding_helper not found, normally in crt1.o/dylib1.o/bundle1.o for architecture i386
  • 原文地址:https://www.cnblogs.com/Blue233333/p/8945182.html
Copyright © 2011-2022 走看看