【最小费用最大流模板】【Uva10806+Spring Team PK】Dijkstra, Dijkstra,

题意:从1到n 再从n到1 不经过重复的,(如果是点就是旅行商问题了),问最短路


建立一个超级源S S到1连一条费用为0,容量为2的边,求费用流即可


如果流<2 那么hehe

否则    输出结果


模板来自Kuangbing 如下:


#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <cstring>
#include <ctime>
#include <algorithm>
#include <iostream>
#include <sstream>
#include <string>
#include <queue>
#define oo 0x13131313
using namespace std;
const int MAXN=200;
const int MAXM=200000;
const int INF=0x3f3f3f3f;
struct Edge
{
    int to,next,cap,flow,cost;
    void get(int a,int b,int c,int d)
    {
        to=a,cap=b,cost=c;next=d;flow=0;
    }
}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)
{
    edge[tol].get(v,cap,cost,head[u]);head[u]=tol++;
    edge[tol].get(u,0,-cost,head[v]);head[v]=tol++;
}
bool spfa(int s,int t)
{
    queue<int>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(s);
    while(!q.empty())
    {
        int u=q.front();
        q.pop();
        vis[u]=false;
        for(int i= head[u];i!=-1;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;
                    q.push(v);
                }
            }
        }
    }
    if(pre[t]==-1) return false;
    else return true;
}
int minCostMaxflow(int s,int t,int &cost)
{
    int flow=0;
    cost = 0;
    while(spfa(s,t))
    {
        int Min=INF;
        for(int i=pre[t];i!=-1;i=pre[edge[i^1].to])
        {
            if(Min >edge[i].cap-edge[i].flow)
              Min=edge[i].cap-edge[i].flow;
        }
        for(int i=pre[t];i!=-1;i=pre[edge[i^1].to])
        {
            edge[i].flow+=Min;
            edge[i^1].flow-=Min;
            cost+=edge[i].cost*Min;
        }
        flow+=Min;
    }
    return flow;
}
int main()
{

}
完整代码如下:

#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <cstring>
#include <ctime>
#include <algorithm>
#include <iostream>
#include <sstream>
#include <string>
#include <queue>
#define oo 0x13131313
using namespace std;
const int MAXN=200;
const int MAXM=200000;
const int INF=0x3f3f3f3f;
struct Edge
{
    int to,next,cap,flow,cost;
    void get(int a,int b,int c,int d)
    {
        to=a,cap=b,cost=c;next=d;flow=0;
    }
}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)
{
    edge[tol].get(v,cap,cost,head[u]);head[u]=tol++;
    edge[tol].get(u,0,-cost,head[v]);head[v]=tol++;
}
bool spfa(int s,int t)
{
    queue<int>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(s);
    while(!q.empty())
    {
        int u=q.front();
        q.pop();
        vis[u]=false;
        for(int i= head[u];i!=-1;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;
                    q.push(v);
                }
            }
        }
    }
    if(pre[t]==-1) return false;
    else return true;
}
int minCostMaxflow(int s,int t,int &cost)
{
    int flow=0;
    cost = 0;
    while(spfa(s,t))
    {
        int Min=INF;
        for(int i=pre[t];i!=-1;i=pre[edge[i^1].to])
        {
            if(Min >edge[i].cap-edge[i].flow)
              Min=edge[i].cap-edge[i].flow;
        }
        for(int i=pre[t];i!=-1;i=pre[edge[i^1].to])
        {
            edge[i].flow+=Min;
            edge[i^1].flow-=Min;
            cost+=edge[i].cost*Min;
        }
        flow+=Min;
    }
    return flow;
}
int NN,MM;
void input()
{
    int a,b,c;
    for(int i=1;i<=MM;i++)
    {
        scanf("%d%d%d",&a,&b,&c);
        addedge(a,b,1,c);
        addedge(b,a,1,c);
    }
}
void solve()
{
       int ANS=0,t;
       addedge(NN+1,1,2,0);            //建立源S=NN+1;
       t=minCostMaxflow(NN+1,NN,ANS);
       if(t==2) printf("%d\n",ANS);
       else printf("hehe\n");
}
void File()
{
    freopen("a.in","r",stdin);
    freopen("a.out","w",stdout);
}
int main()
{
  //  File();
    while(cin>>NN>>MM)
    {
        init(NN+1);
        input();
        solve();
    }
}



你可能感兴趣的:(【最小费用最大流模板】【Uva10806+Spring Team PK】Dijkstra, Dijkstra,)