HOJ 2739 网络流【带权有向图上的中国邮路问题】

【带权有向图上的中国邮路问题】

#include
#include
#include
#include
using namespace std;
typedef long long LL;
const int MAXN=110,M=400000, inf=0x3f3f3f3f;
int head[MAXN];
struct edge{
	int to,next,cost,from;
}e[M];
int anss[M],v[M];
int o,an;
void add(int x,int y,int z)
{
    ee[o].from=x;
    ee[o].to=y;
    ee[o].next=head[x];
	ee[o].cost=z;
	head[x]=o++;
}

struct MCMF
{

    struct Edge
    {
        int from,to,cap,flow,cost;
        Edge(){}
        Edge(int a,int b,int c,int d,int e):from(a),to(b),cap(c),flow(d),cost(e){}
    };

    int n,m,s,t;
    vector edges;
    vector G[MAXN];
    int inq[MAXN],d[MAXN],p[MAXN],a[MAXN];
    queue Q;

    void init(int n)
    {
        this->n=n;
        for(int i=0;ie.flow&&d[e.to]>d[u]+e.cost)
                {
                    d[e.to]=d[u]+e.cost;
                    p[e.to]=G[u][i];
                    a[e.to]=min(a[u],e.cap-e.flow);
                    if(!inq[e.to]) {Q.push(e.to);inq[e.to]=1;}
                }
            }
        }
        if(d[t]==inf) return false;
        flow+=a[t];//固定流量k,检查,若flow+a>=k,只增加k-flow个单位
        cost+=d[t]*a[t];
        int u=t;
        while(u!=s)
        {
            edges[p[u]].flow+=a[t];
            edges[p[u]^1].flow-=a[t];
            u=edges[p[u]].from;
        }
        return true;
    }

    int Mincost(int s,int t)
    {
        int flow=0,cost=0;
        while(SPFA(s,t,flow,cost));
        return cost;
    }
    void solve()
    {
        for (int i=1;i=n-1) continue;
             for (int k=1;k<=e.flow;k++)
                add(e.from,e.to,e.cost);
            }
    }
}it;

int n,m;
int a[2002][3];
int ru[MAXN],chu[MAXN],map[MAXN][MAXN],vis[MAXN];
void dfs(int now)
{   vis[now]=1;
    for (int i=1;i<=n;i++)
         if (map[now][i]&&!vis[i])dfs(i);
}
void DFS(int now)
{
	for (int k=head[now];k!=-1;k=ee[k].next)
	  if (!v[k])
	  {	  v[k]=true;
		  DFS(ee[k].to);
		  anss[an++]=k;
	  }
}
void doit()
{   scanf("%d%d",&n,&m);
    memset(ru,0,sizeof(ru));
    memset(chu,0,sizeof(chu));
    memset(vis,0,sizeof(vis));
    memset(map,0,sizeof(map));
    o=0;memset(head,255,sizeof(head));an=0;
    memset(v,0,sizeof(v));
    int ans=0;
    for (int i=1;i<=m;i++)
        {scanf("%d%d%d",&a[i][0],&a[i][1],&a[i][2]);
         a[i][0]++;a[i][1]++;
         map[a[i][0]][a[i][1]]=1;
         ru[a[i][1]]++;
         chu[a[i][0]]++;
         ans+=a[i][2];
         add(a[i][0],a[i][1],a[i][2]);
        }

    dfs(1);
    for (int i=1;i<=n;i++)
        if (!ru[i]||!chu[i]||!vis[i]){printf("%d\n",-1); return;}
    for (int i=1;i<=n;i++)
        ru[i]=ru[i]-chu[i];
    it.init(n+2);
    for (int i=1;i<=n;i++)
             if (ru[i]>0) it.AddEdge(0,i,ru[i],0);
        else if (ru[i]<0) it.AddEdge(i,n+1,-ru[i],0);
    for (int i=1;i<=m;i++)
        it.AddEdge(a[i][0],a[i][1],inf,a[i][2]);
    printf("%d\n",it.Mincost(0,n+1)+ans);

    it.solve();
    DFS(1);
    for (int i=an-1;i>=0;i--)
        {int p=anss[i];
         printf("%d->%d %d\n",ee[p].from-1,ee[p].to-1,ee[p].cost);
        }
}
int main()
{   int cas;
    scanf("%d",&cas);
    while (cas--) doit();
    return 0;
}


你可能感兴趣的:(【图论】_网络流&&二分图)