【带权有向图上的中国邮路问题】
#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;
}