【最小费用最大流+邻接表】POJ 2135

来源:互联网 发布:苏州大学知博书店 编辑:程序博客网 时间:2024/05/21 14:48

因为有两条不同路径,所以可以这样构图:超级源点s->1,容量为2,边权为0,n->超级汇点t,容量为2,边权为0,其他的点容量为1,边权是输入的数据,这样就保证了肯定有两条不同的路径,而且模型肯定满流,因为这题有重边,所以不能用邻接矩阵,只能用邻接表

#define inf 1<<30#define N 10050struct node{    int u,v,cap,w;    int next;}e[N*6];int head[N/10];int pre[N/10];int dis[N/10];bool vis[N/10];int minc;int ecnt;int min(int a,int b){return a>b?b:a;}void init(){    ecnt = 0;    memset(head,-1,sizeof(head));}void add(int u,int v,int cap,int w){    e[ecnt].u = u;    e[ecnt].v = v;    e[ecnt].cap = cap;    e[ecnt].w = w;    e[ecnt].next = head[u];    head[u] = ecnt++;    e[ecnt].u = v;    e[ecnt].v = u;    e[ecnt].cap = 0;    e[ecnt].w = -w;    e[ecnt].next = head[v];    head[v] = ecnt++;}void spfa(int s,int t){    queue<int> qq;    while(!qq.empty())qq.pop();    int i,j;    while(1){        for(i=s;i<=t;i++){            vis[i] = 0;            dis[i] = inf;            pre[i] = -1;//这里啊!!!初始化啊!!!记录路径啊!!!邻接表啊!!!        }        dis[s] = 0;        qq.push(s);        vis[s] = 1;        while(!qq.empty()){            int u = qq.front();            qq.pop();            vis[u] = 0;            for(int i=head[u];i!=-1;i=e[i].next){                int v = e[i].v;                if(e[i].cap && dis[u] + e[i].w < dis[v]){                    dis[v] = dis[u] + e[i].w;                    pre[v] = i;                    if(!vis[v]){                        vis[v] = 1;                        qq.push(v);                    }                }            }        }        if(pre[t] == -1){            return ;        }        int a = inf;        int k = pre[t];        while(k!=-1){            a = min(a,e[k].cap);            k = pre[e[k].u];        }        k = pre[t];        while(k!=-1){            e[k].cap -= a;            e[k^1].cap += a;//异或就变成了反向边的编号            k = pre[e[k].u];        }        minc += dis[t]*a;    }    return ;}int main(){      int n,m;    while(scanf("%d%d",&n,&m) != -1){        int i,j;        init();        while(m--){            int u,v,w;            scanf("%d%d%d",&u,&v,&w);            add(u,v,1,w);            add(v,u,1,w);        }        add(0,1,2,0);        add(n,n+1,2,0);        int s = 0,t = n+1;        minc = 0;        spfa(s,t);        printf("%d\n",minc);    }    return 0;}