HDU3395(最小费用流)

来源:互联网 发布:免费网吧代理软件 编辑:程序博客网 时间:2024/05/21 00:21

好题

这道题不难,只要注意到在求最小费用的时候不要让流影响到费用就行,最直接的方法就是让图直接满流,然后求最小费用

/* ***********************************************Author        :xdloveCreated Time  :2015年08月18日 星期二 13时18分54秒File Name     :xd.cpp ************************************************ */#include <stdio.h>#include <string.h>#include <iostream>#include <algorithm>#include <vector>#include <queue>#include <set>#include <map>#include <string>#include <math.h>#include <stdlib.h>#include <time.h>using namespace std;/********************************     please don't hack me!! /(ToT)/~~                __------__              /~          ~\             |    //^\\//^\|           /~~\  ||  T| |T|:~\          | |6   ||___|_|_||:|           \__.  /      o  \/'            |   (       O   )   /~~~~\    `\  \         /  | |~~\ |     )  ~------~`\ /' |  | |   /     ____ /~~~)\(_/'   | | |     /'    |    ( |       | | |     \    /   __)/ \       \  \ \      \/    /' \   `\         \  \|\        /   | |\___|           \ |  \____/     | |           /^~>  \        _/ <          |  |         \       \          |  | \        \        \          -^-\  \       |        )               `\_______/^\______/************************************/#define clr(a) memset(a,0,sizeof(a));typedef long long ll;const int MAXN = 220;const int MAXM = 1e4 + MAXN;const int INF = 0x3f3f3f3f;struct DoubleQueue{    int l,r,q[MAXN];    DoubleQueue()    {        l = r = 0;    }    bool empty()    {        return l == r;    }    void push_back(int v)    {        q[r++] = v;        r %= MAXN;    }    void push_front(int v)    {        l = (l - 1 + MAXN) % MAXN;        q[l] = v;    }    int front()    {        return q[l];    }    void pop_front()    {        l++;        l %= MAXN;    }    void pop_back()    {        r = (r - 1 + MAXN) % MAXN;    }};struct Edge{    int to,next,cap,flow,cost;}edge[MAXM];int head[MAXN],tol;int pre[MAXN],dis[MAXN];bool vis[MAXN];int N;void init(int n){    N = n;    tol = 0;    memset(head,-1,sizeof(head));}void addedge(int u,int v,int cap,int cost){    cost *= -1;    //printf("%d %d %d %d\n",u,v,cap,cost);    edge[tol].to = v;    edge[tol].cap = cap;    edge[tol].cost = cost;    edge[tol].flow = 0;    edge[tol].next = head[u];    head[u] = tol++;    edge[tol].to = u;    edge[tol].cap = 0;    edge[tol].cost = -cost;    edge[tol].flow = 0;    edge[tol].next = head[v];    head[v] = tol++;}bool spfa(int s,int t){    DoubleQueue q;    for(int i = 0; i < N; i++)    {        dis[i] = INF;        vis[i] = false;        pre[i] = -1;    }    dis[s] = 0;    vis[s] = true;    q.push_back(s);    while(!q.empty())    {        int u = q.front();        q.pop_front();        vis[u] = false;        for(int i = head[u]; ~i; i = edge[i].next)        {            int v = edge[i].to;            if(edge[i].cap > edge[i].flow && dis[v] > dis[u] + edge[i].cost)            {                dis[v] = dis[u] + edge[i].cost;                pre[v] = i;                if(!vis[v])                {                    vis[v] = true;                    if(!q.empty() && dis[v] <= dis[q.front()])                        q.push_front(v);                    else q.push_back(v);                }            }        }    }    if(pre[t] == -1) return false;    return true;}int Minflow(int s,int t){    int cost = 0;    while(spfa(s,t))    {        int Min = INF;        for(int i = pre[t]; ~i; i = pre[edge[i ^ 1].to])        {            if(Min > edge[i].cap - edge[i].flow)                Min = edge[i].cap - edge[i].flow;        }        //cout<<Min<<endl;        for(int i = pre[t]; ~i; i = pre[edge[i ^ 1].to])        {            edge[i].flow += Min;            edge[i ^ 1].flow -= Min;            cost += edge[i].cost * Min;        }    }    return -cost;}int bit[MAXN];char s[MAXN];int main(){    //freopen("in.txt","r",stdin);    //freopen("out.txt","w",stdout);    int n;    while(~scanf("%d",&n) && n)    {        for(int i = 1; i <= n; i++)            scanf("%d",&bit[i]);        init(n * 2 + 2);        int ss = 0,tt = n * 2 + 1;        for(int i = 1; i <= n; i++)        {            scanf("%s",s);            for(int j = 0; j < n; j++)                if(s[j] == '1' && j != i - 1)                    addedge(i,j + 1 + n,1,bit[i] ^ bit[j + 1]);        }        for(int i = 1; i <= n; i++)        {            addedge(ss,i,1,0);            addedge(i,tt,1,0);            addedge(i + n,tt,1,0);        }        printf("%d\n",Minflow(ss,tt));    }    return 0;}
0 0
原创粉丝点击