http://acm.hdu.edu.cn/showproblem.php?pid=4171

昨天的一道比赛题,这么简单的图论题竟然没A,真的很受伤,,赛后听yyx的点拨后才明白,题意理解错了,题上给了n+1个点和n个路,并不是每个点都和学校相连(当时理解错误),然后枚举除学校的所有点当出口,因为到每个点只有一条路并且都是从报亭出发的,所以如果某个点是出口,那么它到报亭只走一遍,其他都走两遍,,,

#include<iostream>
#include<string.h>
#include<algorithm>
#include<queue>
#include<vector>
#define N 100005
#define inf 0xfffffff
using namespace std;
int visit[N],school[N];
__int64 dis[N];
struct Gnode
{
	Gnode() {}
	Gnode(int num,int len):num(num),len(len){}
	int num,len;
	bool operator<(const Gnode& now)const
	{return now.len<len;}
};
int n;
void spfa(vector<vector<Gnode> >&Graph,int start)
{
	queue<int> Q;
	for(int i=0;i<=n;++i)  dis[i]=inf;
	memset(visit,false,sizeof(visit));
	Q.push(start);
	dis[start]=0;
	visit[start]=true;
	while(!Q.empty())
	{
		int v=Q.front();
		Q.pop();
		visit[v]=false;
		for(int i=0;i<Graph[v].size();++i)
		{
			if(dis[v]!=inf&&dis[v]+Graph[v][i].len<dis[Graph[v][i].num])
			{
				dis[Graph[v][i].num]=dis[v]+Graph[v][i].len;
				if(!visit[Graph[v][i].num])
				{
					visit[Graph[v][i].num]=true;
					Q.push(Graph[v][i].num);
				}
			}
		}
	}
}
int main()
{
	while(~scanf("%d",&n))
	{
		for(int i=0;i<=n;++i) cin>>school[i];
		int sum=0;
		vector<vector<Gnode> >Graph(3*n);
		for(int i=0;i!=n;++i)
		{
			int a,b,c;
			scanf("%d%d%d",&a,&b,&c);
			sum+=c;
			Graph[a].push_back(Gnode(b,c));
			Graph[b].push_back(Gnode(a,c));
		}
		spfa(Graph,0);
		__int64 minx=0xffffffffff;
		for(int i=0;i<=n;++i)  minx=min(2*sum-dis[i]+school[i],minx);
		printf("%I64d\n",minx);
	}return 0;
}



你可能感兴趣的:(http://acm.hdu.edu.cn/showproblem.php?pid=4171)