记录编号 192894 评测结果 AAAAAAAAAA
题目名称 [SGU U206]道路 最终得分 100
用户昵称 Gravatarmikumikumi 是否通过 通过
代码语言 C++ 运行时间 0.065 s
提交时间 2015-10-13 11:24:17 内存使用 0.98 MiB
显示代码纯文本
#include<cstdio>
#include<iostream>
#include<iomanip>
#include<cstring>
#include<deque>
using namespace std;
const int SIZEN=61,SIZEM=410,INF=0x7fffffff/2;
class miku
{
public:
	int fr,to,cost,id;
}E[810];
int N,M,tot=0;
deque<int> s[SIZEN];
int w[SIZEM][SIZEM]={0};
int father[SIZEN]={0},dep[SIZEN]={0},slack;
bool visit[SIZEN]={0};
bool visitx[SIZEM],visity[SIZEM];
int f[SIZEM],lx[SIZEM],ly[SIZEM];
void DFS(int x)
{
	visit[x]=1;
	if(x==1) father[x]=-1;
	for(int i=0;i<s[x].size();i++)
	{
		int v=E[s[x][i]].to;
		if(!visit[v])
		{
		dep[v]=dep[x]+1;
		father[v]=s[x][i];
		DFS(v);
		}
	}
}
void read()
{
	scanf("%d%d",&N,&M);
	int fr,to,w;
	for(int i=1;i<=M;i++)
	{
		scanf("%d%d%d",&fr,&to,&w);
		if(i==N) DFS(1);
		if(i<N)
		{
			s[fr].push_back(tot);
			E[tot++]=(miku){fr,to,w,i};
			s[to].push_back(tot);
			E[tot++]=(miku){to,fr,w,i};
		}
		if(i>=N) E[tot++]=(miku){fr,to,w,i};
	}
}
void add(int x,int y)
{
	miku &F=E[father[x]];
	if(F.cost-E[y].cost>0)
	w[F.id][E[y].id]=F.cost-E[y].cost;
}
void makegragh()
{
	for(int i=2*(N-1);i<tot;i++)
	{
		int v=E[i].fr,u=E[i].to;
		if(dep[v]>dep[u]) swap(v,u);
		while(dep[u]>dep[v]) {add(u,i);u=E[father[u]].fr;}
		while(u!=v) {add(u,i);add(v,i);u=E[father[u]].fr;v=E[father[v]].fr;}
	}
}
bool find(int x)
{
	visitx[x]=1;
	//cout<<x<<endl;
	for(int i=1;i<=M;i++)
	{
		if(visity[i]) continue;
		int t=lx[x]+ly[i]-w[x][i];
		if(t==0)
		{
			visity[i]=1;
			if(f[i]==0||find(f[i]))
			{
				f[i]=x;
				return 1;
			}
		}
		else slack=min(slack,t);
	}
	return 0;
}
int KM()
{
	memset(f,0,sizeof(f));
	memset(ly,0,sizeof(ly));
	for(int i=1;i<=M;i++) lx[i]=INF;
	for(int i=1;i<=M;i++)
	{
		while(1)
		{
			memset(visitx,0,sizeof(visitx));
			memset(visity,0,sizeof(visity));
			slack=INF;
			//for(int j=1;j<=M;j++) cout<<slack[j]<<" "; cout<<endl;
			if(find(i)) break;
			for(int j=1;j<=M;j++) if(visitx[j]) lx[j]-=slack;
			for(int j=1;j<=M;j++) if(visity[j]) ly[j]+=slack;
		}
	}
	int ans=0;
	for(int i=1;i<=M;i++) if(f[i]!=0) ans+=w[f[i]][i];
	return ans;
}
int main()
{
	freopen("sgu206roads.in","r",stdin);
	freopen("sgu206roads.out","w",stdout);
	read();
	makegragh();
	int ans=KM();
	printf("%d",ans);
	return 0;
}