HOJ2739-the Chinese Postman Problem

#include <cstdio>
#include <cstring>
#include <queue>
#include <iostream>
#include <algorithm>
using namespace std;

const int NN=250;
const int MM=200000;
const int INF=0x3fffffff;

int n,m,en,sum,S,T,NV,head[NN],in[NN],out[NN];

struct Edge
{
    int u,v,f,c,next;
    Edge() {}
    Edge(int uu,int vv,int ff,int cc,int tt): u(uu),v(vv),f(ff),c(cc),next(tt) {}
} e[MM];
inline void add(int u,int v,int f,int c)
{
    e[en]=Edge(u,v,f,c,head[u]);
    head[u]=en++;
    e[en]=Edge(v,u,0,-c,head[v]);
    head[v]=en++;
}

int dis[NN],fa[NN];
bool vis[NN];
bool spfa()
{
    for (int i=0; i<NV; i++) vis[i]=0,dis[i]=INF;
    dis[S]=0;
    fa[S]=-1;
    queue<int> q;
    q.push(S);
    while (!q.empty())
    {
        int u=q.front();
        q.pop();
        vis[u]=false;
        for (int i=head[u]; i!=-1; i=e[i].next)
        {
            int v=e[i].v;
            if (e[i].f && dis[v]>dis[u]+e[i].c)
            {
                dis[v]=dis[u]+e[i].c;
                fa[v]=i;
                if (!vis[v])
                {
                    vis[v]=true;
                    q.push(v);
                }
            }
        }
    }
    if (dis[T]!=INF) return true;
    else          return false;
}
int fee_flow()
{
    int cost=0;
    while (spfa())
    {
        int u,v,flow=INF;
        for (v=T; fa[v]!=-1; v=u)
        {
            u=e[fa[v]].u;
            if (flow>e[fa[v]].f) flow=e[fa[v]].f;
        }
        for (v=T; fa[v]!=-1; v=u)
        {
            u=e[fa[v]].u;
            e[fa[v]].f-=flow;
            e[fa[v]^1].f+=flow;
        }
        cost+=dis[T]*flow;
    }
    return cost;
}

int g[NN][NN];
void dfs(int u)
{
    vis[u]=1;
    for (int i=1; i<=n; i++) if (g[u][i] && !vis[i]) dfs(i);
}

int main()
{
    int tt,u,v,d,flag;

    scanf("%d",&tt);
    while (tt--)
    {
        scanf("%d%d",&n,&m);

        sum=en=S=0;
        T=n+1;
        NV=T+1;
        memset(in,0,sizeof(in));
        memset(out,0,sizeof(out));
        memset(g,0,sizeof(g));
        memset(vis,0,sizeof(vis));
        memset(head,-1,sizeof(head));

        for (int i=1; i<=m; i++)
        {
            scanf("%d%d%d",&u,&v,&d);
            u++; v++;
            g[v][u]=1;
            add(u,v,INF,d);
            sum+=d;
            out[u]++; in[v]++;
        }

        dfs(1);
        flag=1;
        for (int i=1; i<=n; i++) if (!vis[i] || !in[i] || !out[i]) flag=0;
        if (!flag) { printf("-1\n"); continue; }

        for (int i=1; i<=n && flag; i++)
        {
            if (in[i]>out[i]) add(S,i,in[i]-out[i],0);
            if (in[i]<out[i]) add(i,T,out[i]-in[i],0);
        }
        printf("%d\n",sum+fee_flow());
    }
    return 0;
}

你可能感兴趣的:(c,struct,include)