记录编号 397992 评测结果 AAAAAAAAAA
题目名称 战争传说 最终得分 100
用户昵称 GravatarFoolMike 是否通过 通过
代码语言 C++ 运行时间 0.084 s
提交时间 2017-04-21 13:55:54 内存使用 4.52 MiB
显示代码纯文本
#include<cstdio>
#include<algorithm>
#include<queue>
using namespace std;
const int N=1e5+10;
struct edge{int f,t,g;}w[N];
int T,n,m,head[N],next[N],flow[N],hd[N],cnt=1;
void add(int f,int t,int g){
	w[++cnt]=(edge){f,t,g};
	next[cnt]=head[f];
	head[f]=cnt;
	w[++cnt]=(edge){t,f,0};
	next[cnt]=head[t];
	head[t]=cnt;
}
struct st{
	int x,i,df;
	st(int X=0,int DF=0){x=X;i=head[x];df=DF;}
}z[N];
int l[N],top,ans;
#define V z[top].x
#define E z[top].i
#define F z[top].df
void change(){
	int df=F;ans+=df;
	for (int i=top-1;i;i--){
		w[z[i].i].g-=df;
		w[z[i].i^1].g+=df;
		z[i].df-=df;
		if (!z[i].df) top=i;
	}
}
queue<int> Q;
void bfs(){
	for (int i=1;i<=n;i++) l[i]=0;
	l[1]=1;Q.push(1);
	while (!Q.empty()){
		int v=Q.front();Q.pop();
		if (l[n]) continue;
		for (int i=head[v];i;i=next[i])
		if (w[i].g&&!l[w[i].t])
			l[w[i].t]=l[v]+1,Q.push(w[i].t);
	}
}
bool dinic(){
	bfs();
	if (!l[n]) return 0;
	z[top=1]=st(1,1e9);
	while (top){
		if (V==n) change(),top--,E=next[E];else
		if (!E) l[V]=0,top--,E=next[E];else
		if (w[E].g&&l[w[E].t]==l[V]+1)
			z[top+1]=st(w[E].t,min(F,w[E].g)),top++;
		else E=next[E];
	}
	return 1;
}
bool go[110][110];
void init(){
	for (int i=1;i<=cnt;i++) w[i].g=flow[i];
	for (int i=1;i<=n;i++) head[i]=hd[i];
}
int main()
{
	freopen("war.in","r",stdin);
	freopen("war.out","w",stdout);
	scanf("%d",&T);
	while (T--){
		while (cnt>1) next[cnt--]=0;
		scanf("%d%d",&n,&m);
		for (int i=1;i<=n;i++) head[i]=0;
		for (int i=1;i<=m;i++){
			int u,v,l;
			scanf("%d%d%d",&u,&v,&l);
			add(u,v,l);
		}
		ans=0;while (dinic());
		int last=ans,Max=0;
		for (int i=1;i<=n;i++)
		for (int j=1;j<=n;j++)
			go[i][j]=0;
		for (int i=1;i<=cnt;i++)
			if (w[i].g) go[w[i].f][w[i].t]=1;
		for (int k=1;k<=n;k++)
		for (int i=1;i<=n;i++)
		for (int j=1;j<=n;j++)
			go[i][j]|=(go[i][k]&&go[k][j]);
		for (int i=1;i<=cnt;i++) flow[i]=w[i].g;
		for (int i=1;i<=n;i++) hd[i]=head[i];
		for (int i=2;i<n;i++)
		for (int j=2;j<n;j++)
		if (!go[i][j]){
			init();
			add(i,j,1e9);
			ans=0;while (dinic());
			Max=max(Max,ans);
			cnt-=2;
		}
		printf("%d\n",Max+last);
	}
	return 0;
}