比赛 20120708 评测结果 AAAAAAAAAA
题目名称 最小最大生成树 最终得分 100
用户昵称 ZhouHang 运行时间 0.648 s
代码语言 C++ 内存使用 22.06 MiB
提交时间 2012-07-08 10:52:38
显示代码纯文本
/**
*Prob	: mstmn
*Data	: 2012-7-8
*Sol	: 骗分
*/

#include <cstdio>
#include <cstring>
#include <algorithm>

#define MaxN 20100
#define MaxE 801000
#define oo 20000000

using namespace std;

struct node {
	int y,c,next,other;
} e[MaxE];
int n,m,s,t,tot=0;
int x[MaxE],y[MaxE],c[MaxE];
int a[MaxN],cur[MaxN],gap[MaxN],pre[MaxN],dis[MaxN];

void insert(int x,int y,int c,int other) {
	e[tot].y = y; e[tot].c = c; e[tot].other = other;
	e[tot].next = a[x]; a[x] = tot;
}

int sap()
 {
     memset(pre,0,sizeof(pre));
     memset(dis,0,sizeof(dis));
     memset(gap,0,sizeof(gap));
     for (int i=0; i<=n+1; i++)
         cur[i] = a[i];
     gap[0]=n; int u = pre[s] = s, maxflow = 0, aug = oo;
     
     while (dis[s]<n) {
 loop:     for (int &i = cur[u]; i; i=e[i].next) {
             int v = e[i].y;
             if (e[i].c && dis[u]==dis[v]+1) {
                 aug = min(aug,e[i].c);
                 pre[v] = u; u=v;
                 if (v==t) {
                     maxflow += aug;
                     for (u=pre[u]; v!=s; v=u,u=pre[u]) {
                         e[cur[u]].c -= aug;
                         e[e[cur[u]].other].c += aug;
                     }
                     aug = oo;
                 }
                 goto loop;
             }
         }
         int mindis = n;
         for (int i=a[u]; i; i=e[i].next) {
             int v = e[i].y;
             if (e[i].c && mindis>dis[v]) {
                 cur[u] = i; mindis = dis[v];
             }
         }
         if ((--gap[dis[u]])==0) break;
         dis[u] = mindis+1;
         gap[dis[u]]++;
         u = pre[u];
     }
     return maxflow;
 }

int main()
{
	freopen("mstmn.in","r",stdin);
	freopen("mstmn.out","w",stdout);
	
	scanf("%d%d",&n,&m);
	for (int i=1; i<=m; i++)
		scanf("%d%d%d",&x[i],&y[i],&c[i]);

	int z;
	scanf("%d%d%d",&s,&t,&z);
	
	//最小生成树
	memset(e,0,sizeof(e));
	memset(a,0,sizeof(a));
	tot = 0;
	for (int i=1; i<=m; i++)
		if (c[i]<z) {
			tot++; insert(x[i],y[i],1,tot+1);
			tot++; insert(y[i],x[i],0,tot-1);
			tot++; insert(y[i],x[i],1,tot+1);
			tot++; insert(x[i],y[i],0,tot-1);
		}
	int ans1 = sap();
	//最大生成树
	memset(e,0,sizeof(e));
	memset(a,0,sizeof(a));
	tot = 0;
	for (int i=1; i<=m; i++)
		if (c[i]>z) {
			if (c[i]==4771&&x[i]==7144)
				bool asfa= 0;
			tot++; insert(x[i],y[i],1,tot+1);
			tot++; insert(y[i],x[i],0,tot-1);
			tot++; insert(y[i],x[i],1,tot+1);
			tot++; insert(x[i],y[i],0,tot-1);
			if (s==400997)
				bool aasd=true;
				
		}
	int ans2 = sap();
		
	printf("%d\n",ans1+ans2);
	
	fclose(stdin); fclose(stdout);
	return 0;
}