codeforces gym-101736 Dessert First Strategy

topic

topic link

answer

It is a typical minimum cut model problem. We know that the point with uncertain color is either white or black, which are two opposite states. We associate with the minimum cut.
The minimum cut is to cut off the weight and the minimum edge set, so that the points in the graph are divided into two point sets, one contains s point, a contains t point, very similar to the requirements of this question.

We construct 3 sets of points.
A set of points are identified as white, with s connected, the flow is i n f .
A set of points are identified as black, with t connected, the flow is i n f .
A group of points of uncertain color, if there is an edge between this point and the white point, then connect an edge corresponding to the flow between this point and the white point. Similar if it is connected to the black point with an edge.

In this case, run the minimum cut/maximum flow once, and the edge that is cut represents the weight that cannot be obtained. Since the cut is the smallest, the rest is the largest.

code

#include <iostream>
#include <cstdio>
#include <vector>
#include <algorithm>
using namespace std;
const int inf = 1e9;
const int maxm = 300001;
const int maxn = 1001;
int node,src,dest,edge;
int ver[maxm],flow[maxm],nxt[maxm];
int head[maxn],work[maxn],dis[maxn],q[maxn];
void prepare(int _node,int _src,int _dest)
{
    node=_node,src=_src,dest=_dest;
    for(int i=0; i<node; ++i)head[i]=-1;
    edge=0;
}
void add_edge(int u,int v,int c)
{
    ver[edge]=v,flow[edge]=c,nxt[edge]=head[u],head[u]=edge++;
    ver[edge]=u,flow[edge]=0,nxt[edge]=head[v],head[v]=edge++;
}
bool Dinic_bfs()
{
    int i,u,v,l,r=0;
    for(i=0; i<node; ++i)dis[i]=-1;
    dis[q[r++]=src]=0;
    for(l=0; l<r; ++l)
        for(i=head[u=q[l]]; i>=0; i=nxt[i])
            if(flow[i]&&dis[v=ver[i]]<0)
            {
                dis[q[r++]=v]=dis[u]+1;
                if(v==dest)return 1;
            }
    return 0;
}
int Dinic_dfs(int u,int exp)
{
    if(u==dest)return exp;
    for(int &i=work[u],v,tmp; i>=0; i=nxt[i])
        if(flow[i]&&dis[v=ver[i]]==dis[u]+1&&(tmp=Dinic_dfs(v,min(exp,flow[i])))>0)
        {
            flow[i]-=tmp;
            flow[i^1]+=tmp;
            return tmp;
        }
    return 0;
}
int Dinic_flow()
{
    int i,ret=0,delta;
    while(Dinic_bfs())
    {
        for(i=0; i<node; ++i)work[i]=head[i];
        while(delta=Dinic_dfs(src,inf))ret+=delta;
    }
    return ret;
}
typedef pair<int,int> pii;
vector<pii> vec[100007];
int n,k,p,qq,tmp;
int kind[205];
int pkind[100007];
int G[205][205];
int ans;
int mxcut;
#define pr(x) cout<<#x<<":"<<x<<endl
void dfs(int u,int fa){
    for(pii p : vec[u]){
        int v = p.first,c = p.second;
        int k1 = kind[pkind[u]];
        int k2 = kind[pkind[v]];
        if(u > v) goto s;
        if(pkind[u] == pkind[v]) {
            ans += c;
            goto s;
        }
        if(k1 && k2){
            if(k1 == k2) ans += c;
        }
        if(!k1 && !k2){
            add_edge(pkind[u],pkind[v],c),mxcut += c;
        }
        if(k1 && !k2){
            if(k1 == -1) add_edge(pkind[u],pkind[v],c),mxcut += c;
            if(k1 == 1 ) add_edge(pkind[v],pkind[u],c),mxcut += c;
        }
        if(!k1 && k2){
            if(k2 == -1) add_edge(pkind[v],pkind[u],c),mxcut += c;
            if(k2 == 1 ) add_edge(pkind[u],pkind[v],c),mxcut += c;
        }
s:      
        if(v != fa) dfs(v,u);
    }
}
int lp,rp;
int main(){
    scanf("%d %d %d %d",&n,&k,&p,&qq);
    for(int i = 1;i <= p;++i) scanf("%d",&tmp),kind[tmp] -= 1;
    for(int i = 1;i <= qq;++i) scanf("%d",&tmp),kind[tmp] += 1;
    for(int i = 1;i <= n;++i) scanf("%d",&tmp),pkind[i] = tmp;
    prepare(k+2,0,k+1);
    for(int i = 1;i <= k;++i) {
        if(kind[i] == -1) add_edge(0,i,inf);
        if(kind[i] == 1 ) add_edge(i,k+1,inf);
    }
    for(int i = 1;i < n;++i){
        int u,v,c;scanf("%d%d%d",&u,&v,&c);
        vec[u].push_back(make_pair(v,c));
        vec[v].push_back(make_pair(u,c));
    }

    dfs(1,0);
    ans += mxcut - Dinic_flow();
    cout<<ans<<endl;
}

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325740887&siteId=291194637