# 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
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);}
32     bool bfs()
33     {
34         memset(dis,0,sizeof(dis)); dis[s]=1;
37         {
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 {
112     for (int i=1;i<=n;i++) {ss[i]=qread(); if (ss[i]>0) sum+=ss[i];}
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\n",ans);
126     return 0;
127 }
View Code

posted @ 2018-04-25 15:41  Blue233333  阅读(220)  评论(0编辑  收藏  举报