zoukankan      html  css  js  c++  java
  • POJ2135

    最小费用最大流模板题

    题意就是要找两条无交集的从1到n的路线,使距离和最小。

    每条路只能走一次。

    设置一个源,接到1点,设置一个汇,从n点接到汇。

    为保证无交集,我们把每条边的流量设置为1,而源发出的流量和汇接收的流量均为2。每条边的费用就是该边在原图中的权值。

     1 #include <cstdio>
     2 #include <iostream>
     3 #include <string.h>
     4 #include <queue>
     5 using namespace std;
     6 const int N=1050;
     7 const int M=10050;
     8 struct{
     9     int v, cap, cost, next, re;//re 逆边的下标
    10 }e[M];
    11 int n,m,ans,k;
    12 int first[N],pre[N],dis[N];
    13 void init(){
    14     k=0;
    15     memset(first,-1,sizeof(first));
    16     ans=0;
    17 }
    18 void addedge(int u,int v,int ca,int co){
    19     e[k].v=v;
    20     e[k].cap=ca;
    21     e[k].cost=co;
    22     e[k].next=first[u];
    23     e[k].re=k+1;
    24     first[u]=k++;
    25     e[k].v=u;
    26     e[k].cap=0;
    27     e[k].cost=-co;
    28     e[k].next=first[v];
    29     e[k].re=k-1;
    30     first[v]=k++;
    31 }
    32 bool spfa(int s,int t){
    33     memset(dis,0x3f,sizeof(dis));
    34     queue<int >q;
    35     int inq[N]={0};
    36     q.push(s);
    37     inq[s]=1;
    38     dis[0]=0;
    39     while(!q.empty()){
    40         int u=q.front();
    41         q.pop();
    42         for(int i=first[u];i!=-1;i=e[i].next){
    43             int v=e[i].v;
    44             if(e[i].cap&&dis[v]>dis[u]+e[i].cost){
    45 
    46                 dis[v]=dis[u]+e[i].cost;
    47                 pre[v]=i;
    48                 if(!inq[v]){
    49                     inq[v]=1;
    50                     q.push(v);
    51                 }
    52             }
    53         }
    54         inq[u]=0;
    55     }
    56     if(dis[t]==0x3f3f3f3f){return false;}
    57     return true;
    58 }
    59 void solve(){
    60     int u, p, sum = 1<<30;
    61     for(u = n; u != 0; u = e[e[p].re].v){
    62         p = pre[u];
    63         sum = min(sum, e[p].cap);
    64     }
    65     for(u = n; u != 0; u = e[e[p].re].v){
    66         p = pre[u];
    67         e[p].cap -= sum;
    68         e[e[p].re].cap += sum;
    69         ans += sum * e[p].cost;
    70     }
    71 }
    72 int main(){
    73     int u,v,c;
    74     init();
    75     scanf("%d%d",&n,&m);
    76     while(m--){
    77         scanf("%d%d%d",&u,&v,&c);
    78         addedge(u,v,1,c);
    79         addedge(v,u,1,c);
    80     }
    81     addedge(0,1,2,0);
    82     addedge(n,n+1,2,0);
    83 
    84     n++;
    85     while(spfa(0,n)){solve();}
    86     printf("%d
    ",ans);
    87     return 0;
    88 }
  • 相关阅读:
    python之re(正则表达式)
    virtualbox之下载地址
    数据库之sqlite
    vmware 虚拟机扩展 liunx系统硬盘空间
    常见python面试题-手写代码系列
    Python的Struct模块
    mac上安装brew如何加速
    outlook数字证书导出、导入及解决老是弹出macOS需要访问系统钥匙串弹窗问题
    docker命令学习
    Message from syslogd不停的打日志
  • 原文地址:https://www.cnblogs.com/Mr-Xu-JH/p/4352306.html
Copyright © 2011-2022 走看看