bzoj4873- closed subgraph maximum weight

  1 #include<iostream>
  2 #include<cstdio>
  3 #include<cmath>
  4 #include<string>
  5 #include<cstring>
  6 #include<algorithm>
  7 #include<iomanip>
  8 #include<queue>
  9 using namespace std;
 10 namespace Moxing {
 11     const int N=105,M=1005;
 12     const int inf=0x3f3f3f3f;
 13     int n,m,a[N],mp[N][N],id[N][N],idw[M],ict,S,T,cnt=1,last[30303];
 14     long long sum;
 15     bool vis[M];
 16     struct node {
 17         int to,dis,nxt;
 18     } edge[30303<<6];
 19     void add(int from,int to,int dis) {
 20         edge[++cnt].to=to,edge[cnt].dis=dis,edge[cnt].nxt=last[from],last[from]=cnt;
 21         //    edge[++cnt].to=from,edge[cnt].dis=dis,edge[cnt].nxt=last[from],last[from]=cnt;
 22     }
 23     void insert(int from,int to,int dis) {
 24         add(from,to,dis),add(to,from,0);
 25     //    cout<<from<<' '<<to<<' '<<dis<<endl;
 26     }
 27     void build() {
 28         for(int i=1; i<=n; i++) {
 29             for(int j=i; j<=n; j++) {
 30                 id[i][j]=++ict;
 31             }
 32         }
 33         for(int i=1; i<=n; i++) {
 34             if(vis[a[i]]) continue ;
 35             vis[a[i]]=1,idw[a[i]]=++ict;
 36         }
 37         //    memset(vis,0,sizeof(vis));
 38         S=0,T=ict+n+1;
 39         for(int i=1; i<=n; i++) {
 40             for(int j=i; j<=n; j++) {
 41                 if(mp[i][j]>0) {//1
 42                     insert(S,id[i][j],mp[i][j]);//cout<<'1'<<' ';
 43                 } else if(mp[i][j]<0) {
 44                     insert(id[i][j],T,-mp[i][j]);//cout<<'1'<<' ';
 45                 }
 46                 insert(id[i][j],ict+i,inf);//2
 47                 insert(id[i][j],ict+j,inf);//cout<<'2'<<' ';
 48                 if(i!=j) { //5
 49                     insert(id[i][j],id[i+1][j],inf);
 50                     insert(id[i][j],id[i][j-1],inf);//cout<<'5'<<' ';
 51                 }
 52             }
 53         }
 54         memset(vis,0,sizeof(vis));
 55         for(int i=1; i<=n; i++) {
 56             if(vis[a[i]]) continue ;
 57             vis[a[i]]=1,insert(idw[a[i]],T,m*a[i]*a[i]);//cout<<'3'<<' ';//3
 58         }
 59         for(int i=1; i<=n; i++) {
 60             insert(ict+i,idw[a[i]],inf);//4
 61             insert(ict+i,T,a[i]);//cout<<'4'<<' ';
 62         //    cout<<"Moxing"; 
 63         }
 64         //    cout<<endl;
 65         return ;
 66     }
 67     int d[M*10];
 68     bool bfs() {
 69         memset(d,0,sizeof(d));
 70         queue<int>q;
 71         d[S]=1;
 72         q.push(S);
 73         while(!q.empty()) {
 74             int x=q.front();
 75             q.pop();
 76             for(int i=last[x]; i; i=edge[i].nxt) {
 77                 int y=edge[i].to;
 78                 if(!d[y] && edge[i].dis) {
 79                     d[y]=d[x]+1;
 80                     q.push(y);
 81                     //cout<<y<<' ';
 82                 }
 83             }
 84         }
 85         //cout<<d[T]<<' ';
 86         return d[T];
 87     }
 88     int dfs(int x,int lim) {
 89         if(x==T) return lim;
 90         int f=0,tmp;
 91         for(int i=last[x]; i; i=edge[i].nxt) {
 92             int y=edge[i].to;
 93             if(d[y]==d[x]+1&&edge[i].dis&&(tmp=dfs(y,min(lim,edge[i].dis)))) {
 94                 edge[i].dis-=tmp,edge[i^1].dis+=tmp;
 95                 lim-=tmp;
 96                 f+=tmp;
 97                 if(!lim) return f;
 98             }
 99         }
100         d[x]=0;
101         return f;
102     }
103     long long dinic() {
104         long long res=0;
105         //    cout<<dfs(S,inf)<<' ';
106         while(bfs()) res+=dfs(S,inf);
107         return res;
108     }
109     struct main {
110         main() {
111             scanf("%d%d",&n,&m);
112             for(int i=1; i<=n; i++) {
113                 scanf("%d",&a[i]);
114             }
115             for(int i=1; i<=n; i++) {
116                 for(int j=i; j<=n; j++) {
117                     scanf("%d",&mp[i][j]);
118                     if(mp[i][j]>0) sum+=mp[i][j];
119                 }
120             }
121             build();
122             long long res=dinic();
123             //    printf("%lld\n",res);
124             sum-=res;
125             printf("%lld\n",sum);
126             exit(0);
127         }
128     } UniversalLove;
129 }
130 int main() {
131     Moxing::main();
132 }
View Code

Closed subgraph maximum weight
a directed graph, each point has a weight (which may be positive or negative or zero), and selecting a maximum weight subgraph, such that each point in the subsequent sub-picture inside this is called the maximum weight subgraph closed subgraph.
FIG construction: from source s connected to each point is the right side of a weight capacity of each node to sink negative weights attached t an edge weight capacity of absolute value, the original edges have capacity to FIG. all is infinite

The answer is a positive sum of weights - minimum cut

why? The following is quoted from: https: //www.cnblogs.com/dilthey/p/7565206.html

In this case, it is possible to obtain small CONCLUSION:
① the right side with respect to the minimum cut of FIG st, simple cut;
  Simple cut: cutset all sides, are connected with s or t.
  Obviously, because not with s, t connected to the side, weights are INF, minimum cut can not cut the edge of the INF;
  this early in the article http://www.cnblogs.com/dilthey/p/7401563. html mentioned in there appeared, in fact, with the right edge of the directed graph is a bipartite graph;

each of two subgraphs generated by simple cut ② in the figure, we note comprising FIG point s is s, contains a point FIG t is T, then S is closed in FIG. FIG.;
  closed figure: in the figure, we selected a number of dots set, if any point of attachment to any set of the arcs, are the end points in V, then the All of these set of edges form a closed and FIG.
  Proof: Simple cutting edge weight is not included within the INF side, i.e. does not contain two side communication graph (except at the connection point of the side t);
  i.e., no edge map S T Fig communication, then, All edges are only connected to the S in FIG., namely the closure of FIG.

③ minimal cut generated map S and T, S is closed subgraph FIG maximum power;
  Maximum Weight closed subgraph: Throughout the drawings, FIG plurality of sub-conditions is a closed figure, the point where the sum of the maximum weight and closing the sub-view of the maximum power;
  as cutset all sides, than to the s, is connected to a T;
  we write cutset, edge weights of all connections in s and is x1, all connections weight on t sides and is x2, and the cutset all sides weigh is X = x1 + x2;
  and, weights and to W at all points denoted in FIG S, note where the value is the right and by w1 , and the weighted sum is negative - w2, so that W = w1 - w2;
  and W + X = w1 - w2 + x1 + x2, x2 = w2 since
    (Because the point of all negative weights in FIG S, the bound connected to the t-point, and the map S are bound to the t separated; so cutset, "connected to the t-point edge weights and" is "map S all the weighted sum of the negative weights point and, negation ")
  thus W + X = w1 + x1;
  and apparent, w1 + x1 is the value of all positive weights throughout the figures and referred to as the sUM;
  so that W = sUM - X, i.e., "power values of all points of the map S and" = "all positive weights of the entire figure and" - "cutset all edge weight value";
  then, as sUM is a constant value, if we take the minimum cut , the "weight of all the points of view of S and" is the greatest, that at this time is a diagram showing an S S is closed subgraph maximum weight;
 

and finally, we have a complete idea of solving such problems:
  ① first record the entire FIG, all weights punctual and;
  ② correspondence flow network, seeking maximum flow, maximum flow equal to the minimum cut in value, so we get st flow network minimum cut;
  ③ "all punctual weights and" Save to "ST minimum cut", i.e. the maximum weight to give the sub-closed weights and FIG.

Guess you like

Origin www.cnblogs.com/Moxingtianxia/p/11370294.html