P4553 80 people around the world and down stream sector costs

  Meaning of the questions:

There are 1-n m individual cities have to travel each person only from a small number of large cities to the number of city spending costs COSTij beginning everyone can start a trip from any city and each city exactly Vi individuals through ( after a start can be considered) ask minimum cost

 

Obviously there are costs with upper and lower bounds of the flow is very easy to understand each point even split between two points lower and upper bounds are represented just by Vi Vi classic even then people can re-map the control head count m run template (front built Figure)

#include<bits/stdc++.h>
using namespace std;
//input by bxd
#define rep(i,a,b) for(int i=(a);i<=(b);i++)
#define repp(i,a,b) for(int i=(a);i>=(b);--i)
#define RI(n) scanf("%d",&(n))
#define RII(n,m) scanf("%d%d",&n,&m)
#define RIII(n,m,k) scanf("%d%d%d",&n,&m,&k)
#define RS(s) scanf("%s",s);
#define ll long long
#define pb push_back
#define inf 0x3f3f3f3f
#define CLR(A,v)  memset(A,v,sizeof A)
//////////////////////////////////
const int N=100001;

ll maxflow,mincost;
int last[N],pre[N],dis[N],flow[N],d[N];
bool vis[N];
struct Edge{
    int next,to,flow,dis;
}edge[N<<1];
int pos=1,head[N];
void init()
{
    pos=1;
    CLR(head,0);
    mincost=maxflow=0;
}
queue <int> q;
inline void add(int from,int to,int flow,int dis)//flow流量 dis费用
{
    edge[++pos].next=head[from];
    edge[pos].flow=flow;
    edge[pos].dis=dis;
    edge[pos].to=to;
    head[from]=pos;

    edge[++pos].next=head[to];
    edge[pos].flow=0;
    edge[pos].dis=-dis;
    edge[pos].to=from;
    head[to]=pos;

}
void ins(int x,int y,int down,int up,int cost)
{
    add(x,y,up-down,cost);
    d[x]-=down;
    d[y]+=down;
}

bool spfa(int s,int t)
{
    CLR(dis,0x3f);
    CLR(flow,0x3f);
    CLR(vis,0);
    while (!q.empty()) q.pop();
    dis[s]=0; pre[t]=-1; q.push(s); vis[s]=1;
    int tot=0;
    while (!q.empty())
    {
        int now=q.front(); q.pop(); vis[now]=0;
        for (int i=head[now]; i; i=edge[i].next)
        {
            int to=edge[i].to;
            if  (edge[i].flow>0 && dis[to]>dis[now]+edge[i].dis)
            {
                dis[to]=edge[i].dis+dis[now];
                flow[to]=min(edge[i].flow,flow[now]);
                last[to]=i;
                pre[to]=now;
                if (!vis[to])
                {
                    q.push(to); vis[to]=1;
                }
            }
        }
    }
    return pre[t]!=-1;
}
inline void MCMF(int s,int t)
{
    while (spfa(s,t))
    {
        int now=t;
        maxflow+=flow[t];
        mincost+=flow[t]*dis[t];
        while (now!=s)
        {
            edge[last[now]].flow-=flow[t];//dis . flow
            edge[last[now]^1].flow+=flow[t];
            now=pre[now];
        }
    }
}
int n,m,s,t,ss,x,a,b,S,T;

int main()
{
    scanf("%d%d",&n,&m);

    s=2*n+1,ss=s+1,t=ss+1,S=t+1,T=S+1;

    ins(s,ss,m,m,0);

    rep(i,1,n)scanf("%d",&x),ins(i,i+n,x,x,0),ins(ss,i,0,m,0),ins(i+n,t,0,m,0);
    rep(i,1,n-1)
    rep(j,i+1,n)
    {
        scanf("%d",&x);
        if(x!=-1)
        ins(i+n,j,0,m,x);
    }
    ins(t,s,0,inf,0);
    rep(i,1,t)
    if(d[i]>0)add(S,i,d[i],0);
    else if(d[i]<0)add(i,T,-d[i],0);

    MCMF(S,T);
    cout<<mincost;

    return 0;
}
View Code

 

Can also use ordinary minimum cost maximum flow (model built into FIG vertex cover)

And before doing interstellar racing are very similar to the bipartite graph minimum vertex cover model but vertex vi times the coverage requirements

Each point is split into and out points on the well done (to fully understand the in and out points are not used to do in this kind of meaning even i and i + n is not more than Vi Vi such as this point after a maximum of k times) (and napkins question is a bit like every night harvest  ai dirty towel bar every morning  harvest ai  clean and dirty towel that is certainly fixed good)

 

 

Clearly vertex as previously coverage model point --T - Vi - 0 S-- Out point --Vi - 0 each point represents a fixed number of times to traverse

A point - can reach the point --m (inf also line) - the COST

S - SS - m - 0 (control number)

SS-- point --m - 0 (here it must be connected to the point S is a point of understanding it)

Can also reach a point considered to be the point of departure is considered a better understanding

#include<bits/stdc++.h>
using namespace std;
//input by bxd
#define rep(i,a,b) for(int i=(a);i<=(b);i++)
#define repp(i,a,b) for(int i=(a);i>=(b);--i)
#define RI(n) scanf("%d",&(n))
#define RII(n,m) scanf("%d%d",&n,&m)
#define RIII(n,m,k) scanf("%d%d%d",&n,&m,&k)
#define RS(s) scanf("%s",s);
#define ll long long
#define pb push_back
#define inf 0x3f3f3f3f
#define CLR(A,v)  memset(A,v,sizeof A)
//////////////////////////////////
const int N=100001;

ll maxflow,mincost;
int last[N],pre[N],dis[N],flow[N];
bool vis[N];
struct Edge{
    int next,to,flow,dis;
}edge[N<<1];
int pos=1,head[N];
void init()
{
    pos=1;
    CLR(head,0);
    mincost=maxflow=0;
}
queue <int> q;
inline void add(int from,int to,int flow,int dis)//flow流量 dis费用
{
    edge[++pos].next=head[from];
    edge[pos].flow=flow;
    edge[pos].dis=dis;
    edge[pos].to=to;
    head[from]=pos;

    edge[++pos].next=head[to];
    edge[pos].flow=0;
    edge[pos].dis=-dis;
    edge[pos].to=from;
    head[to]=pos;

}
bool spfa(int s,int t)
{
    CLR(dis,0x3f);
    CLR(flow,0x3f);
    CLR(vis,0);
    while (!q.empty()) q.pop();
    dis[s]=0; pre[t]=-1; q.push(s); vis[s]=1;
    int tot=0;
    while (!q.empty())
    {
        int now=q.front(); q.pop(); vis[now]=0;
        for (int i=head[now]; i; i=edge[i].next)
        {
            int to=edge[i].to;
            if  (edge[i].flow>0 && dis[to]>dis[now]+edge[i].dis)
            {
                dis[to]=edge[i].dis+dis[now];
                flow[to]=min(edge[i].flow,flow[now]);
                last[to]=i;
                pre[to]=now;
                if (!vis[to])
                {
                    q.push(to); vis[to]=1;
                }
            }
        }
    }
    return pre[t]!=-1;
}
inline void MCMF(int s,int t)
{
    while (spfa(s,t))
    {
        int now=t;
        maxflow+=flow[t];
        mincost+=flow[t]*dis[t];
        while (now!=s)
        {
            edge[last[now]].flow-=flow[t];//dis . flow
            edge[last[now]^1].flow+=flow[t];
            now=pre[now];
        }
    } 
} 
Int n-, m, S, T, SS, X, A, B; 

int main () 
{ 
    Scanf ( " % D% D " , & n-, & m); 
    S = 2 * n-+ . 1 , SS = S + . 1 , T = SS + . 1 ; 
    the Add (S, SS, m, 0 ); 
    REP (I, . 1 , n-) Scanf ( " % D " , & X), the Add (S, I, X, 0 ), the Add (I + n-, T, x, 0 ), the Add (SS, n-I +, x, 0 ); // SS inf and m are even, but preferably is connected ac x as a topic that exactly x 

    REP (I, . 1 , N- 1 )
    rep(j,i+1,n)
    {
        scanf("%d",&x);
        if(x!=-1)
        add(i,j+n,inf,x);
    }
    
    MCMF(s,t);
    cout<<mincost;

    return 0;
}
View Code

 

Guess you like

Origin www.cnblogs.com/bxd123/p/11308284.html