码迷,mamicode.com
首页 > 其他好文 > 详细

321B

时间:2017-11-26 15:52:59      阅读:193      评论:0      收藏:0      [点我收藏+]

标签:line   template   class   inline   r++   struct   UI   memset   log   

321B
MCMF必须是满足流量最大为前提下的最小费用流(这里是最大费用流)
因此还必须不断地枚举m的流量才行

#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<queue>
using namespace std;
const int maxn = 1e5+11;
const int oo = 0x3f3f3f3f;
int to[maxn<<1],cost[maxn<<1],cap[maxn<<1],flow[maxn<<1],nxt[maxn<<1];
int head[maxn],tot;
void init(){
    memset(head,-1,sizeof head);
    tot=0;
}
void add(int u,int v,int c,int w){
    to[tot]=v;
    cap[tot]=c;
    flow[tot]=0;
    cost[tot]=w;
    nxt[tot]=head[u];
    head[u]=tot++;
    swap(u,v);
    to[tot]=v;
    cap[tot]=0;
    flow[tot]=0;
    cost[tot]=-w;
    nxt[tot]=head[u];
    head[u]=tot++;
}
struct QUEUE{
    int que[maxn];
    int front,rear;
    void init(){front=rear=0;}
    void push(int x){que[rear++]=x;}
    int pop(){return que[front++];}
    bool empty(){return front==rear;}
}que;
int n,m,s,t;
int dis[maxn],pre[maxn];
bool vis[maxn];
bool spfa(){
    que.init();
    memset(dis,0x80,sizeof dis);
    memset(vis,0,sizeof vis);
    memset(pre,-1,sizeof pre);
    que.push(s);dis[s]=0;vis[s]=1;
    while(!que.empty()){
        int u = que.pop();
        vis[u]=0;
        for(int i = head[u]; ~i; i = nxt[i]){
            int v=to[i],c=cap[i],f=flow[i],w=cost[i];
            if(c>f&&dis[v]<dis[u]+w){
                dis[v]=dis[u]+w;
                pre[v]=i;
                if(!vis[v]){
                    vis[v]=1;
                    que.push(v);
                }
            }
        }
    }
    if(pre[t]==-1)return 0;
    return 1;
}
int mcmf(){
    int mc=0,mf=0;
    while(spfa()){
        int mn=oo;
        for(int i = pre[t]; ~i; i = pre[to[i^1]]){
            mn=min(mn,cap[i]-flow[i]);
        }
        for(int i = pre[t]; ~i; i = pre[to[i^1]]){
            flow[i]+=mn;
            flow[i^1]-=mn;
            mc+=cost[i]*mn;
        }
        mf+=mn;
    }
    return mc;
}
int n1,n2,n3,a[maxn],b[maxn],atr[maxn],x;
char str[199];
int main(){
    while(scanf("%d%d",&n1,&n2)!=EOF){
        init();
        if(n1<n2){
            n3=n2-n1;
            n=2*n2+2;
            t=n;s=t-1;
        }
        else{
            n3=0;
            n=n1+n2+2;
            t=n;s=n-1;  
        }
        for(int i = 1; i <= n1; i++){
            scanf("%s%d",str,&a[i]); 
            if(str[0]==‘A‘) atr[i]=1;
            else atr[i]=0;
        }
        for(int i = 1; i <= n2; i++){
            scanf("%d",&b[i]);
        }
        if(n3) for(int i = 1; i <= n3; i++){
            atr[i+n1]=1;
            a[i+n1]=0;
        }
        for(int i = 1; i <= n2; i++){
            add(s,i,1,0);
        }
        for(int i = 1; i <= n1+n3; i++){
            add(i+n2,t,1,0);
        }
        for(int i = 1; i <= n2; i++){
            for(int j = 1; j <= n1+n3; j++){
                if(atr[j]==1){
                    if(b[i]>=a[j]){
                        if(a[j]!=-oo) add(i,j+n2,1,b[i]-a[j]);
                        else add(i,j+n2,1,b[i]);
                    }
                    else add(i,j+n2,1,-9999);
                }
                else{
                    if(b[i]>a[j]){
                        add(i,j+n2,1,0);
                    }
                    else add(i,j+n2,1,-9999);
                }
            }
        } 
        printf("%d\n",mcmf());
    }
    return 0;
}
#include <bits/stdc++.h>



#define inf 0x3f3f3f3f

#define INF 0x3f3f3f3f3f3f3f3fLL

#define mod 1000000007

#define pb push_back

#define sq(x) ((x)*(x))

#define sz(a) ((int)a.size())

#define x first

#define y second

#define eps 1e-8

#define bpt(x) (__builtin_popcount(x))

#define bptl(x) (__builtin_popcountll(x))

#define bit(x, y) (((x)>>(y))&1)

#define bclz(x) (__builtin_clz(x))

#define bclzl(x) (__builtin_clzll(x))

#define bctz(x) (__builtin_ctz(x))

#define bctzl(x) (__builtin_ctzll(x))

#define rands(n) (rand()%n+1)

#define rand0(n) (rands(n)-1)

#define Rands(n) ((INT)rand()*rand()%n+1)

#define Rand0(n) (Rands(n)-1)

#define PQ priority_queue<pii, vector<pii>, greater<pii> >

#define rep(i, a, b) for(int i=a; i<b; i++)



using namespace std;

typedef long long INT;

typedef vector<int> VI;

typedef pair<int, int> pii;

typedef pair<INT, INT> PII;

typedef pair<pii, int> ppi;

typedef double DO;



template<typename T, typename U> inline void smin(T &a, U b) {if (a>b) a=b;}

template<typename T, typename U> inline void smax(T &a, U b) {if (a<b) a=b;}



template<class T>inline void gn(T &x) {char c, sg=0; while (c=getchar(), (c>‘9‘ || c<‘0‘) && c!=‘-‘);for((c==‘-‘?sg=1, c=getchar():0), x=0; c>=‘0‘ && c<=‘9‘; c=getchar()) x=(x<<1)+(x<<3)+c-‘0‘;if (sg) x=-x;}

template<class T>inline void print(T x) {if (x<0) {putchar(‘-‘);return print(-x);}if (x<10) {putchar(‘0‘+x);return;} print(x/10);putchar(x%10+‘0‘);}

int power(int a, int b, int m, int ans=1) {

    for (; b; b>>=1, a=1LL*a*a%m) if (b&1) ans=1LL*ans*a%m;

    return ans;

}



#if ( ( _WIN32 || __WIN32__ ) && __cplusplus < 201103L)

    #define lld "%I64d"

#else

    #define lld "%lld"

#endif



#define NN 400

#define MC 100000



int N, M, a[NN], b[NN], V, src, tar, mx, S, T;

int adj[NN][NN], cap[NN][NN], cost[NN][NN];

int dis[NN], q[NN*NN], qf, qb, pre[NN], C, deg[NN];

char s[NN][10];



void init() {

    memset(pre, -1, sizeof(pre));

    memset(deg, 0, sizeof(deg));

}

void add_edge(int u, int v, int w, int c) {

    adj[u][deg[u]++]=v;

    adj[v][deg[v]++]=u;

    cap[u][v]=w; cap[v][u]=0;

    cost[u][v]=c; cost[v][u]=-c;

}

int Mincost_Maxflow() {

    int ans=0, bot; C=0;

    while(1) {

        memset(dis, 0x3f, sizeof(dis));

        qf=qb=0;

        dis[src]=0; q[qb++]=src;

        while(qf<qb) {

            int u=q[qf++];

            for(int i=0; i<deg[u]; i++) {

                int v=adj[u][i];

                if(cap[u][v]==0) continue;

                if(dis[v]>dis[u]+cost[u][v]) {

                    dis[v]=dis[u]+cost[u][v];

                    q[qb++]=v;

                    pre[v]=u;

                }

            }

        }

        if(dis[tar]>=inf) return ans;

        bot=inf;

        for(int u=tar; u!=src; u=pre[u]) bot=min(bot, cap[pre[u]][u]);

        ans+=bot;

        for(int u=tar; u!=src; u=pre[u]){

            cap[pre[u]][u]-=bot;

            cap[u][pre[u]]+=bot;

        }

        C+=dis[tar]*bot;

    }

    return ans;

}

int main() {
    gn(N); gn(M);
    for(int i=1; i<=N; i++) {
        scanf("%s", s[i]);  gn(a[i]);
    }
    for(int i=1; i<=M; i++)  gn(b[i]);
    src=0; tar=M+N+1; S=M+N+2; T=M+N+3;
    for(int k=1; k<=M; k++) {
        init();
        add_edge(src, S, k, 0);
        for(int i=1; i<=M; i++) {
            add_edge(S, i, 1, 0);
            add_edge(i, T, 1, -b[i]);
            for(int j=1; j<=N; j++) {
                if(b[i]>=a[j] && s[j][0]==‘A‘) add_edge(i, j+M, 1, a[j]-b[i]);
                else if(b[i]>a[j] && s[j][0]==‘D‘) add_edge(i, j+M, 1, 0);
            }
        }
        for(int i=1; i<=N; i++) add_edge(M+i, tar, 1, 0);
        add_edge(T, tar, M, MC);
        Mincost_Maxflow();
        if(cap[tar][T]>max(0, k-N)) continue;
        mx= max(mx, -C+cap[tar][T]*MC);
    }
    printf("%d\n", mx);
    return 0;
}

321B

标签:line   template   class   inline   r++   struct   UI   memset   log   

原文地址:http://www.cnblogs.com/caturra/p/7899064.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!