#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;
}
HOJ2739-the Chinese Postman Problem
最新推荐文章于 2019-03-01 15:38:31 发布

657

被折叠的 条评论
为什么被折叠?



