xynuoj 1596: 香甜的黄油

最短路问题

注意:

1.使用邻接数组存储会超时,需要使用邻接表。

2.从每一个牧场枚举到各个奶牛的距离,并把他们的最小和保存。


#include<stdio.h>
#include<algorithm>
#include<queue>
#include<string.h>
#include<math.h>
using namespace std;
#define INF 0x3f3f3f
#define MAXN 808
int n,p,c;
struct Edge
{
	int v;
	int cost;
	Edge(int _v = 0, int _cost = 0) : v(_v), cost(_cost) {}
};
vector<Edge> E[MAXN];
void addEdge(int u, int v, int w)
{
	E[u].push_back(Edge(v, w));
	E[v].push_back(Edge(u, w));
}
int mu[MAXN];
bool vis[MAXN]; // 在队列列标志
int cnt[MAXN]; // 每个点的?入列列队次数
int dist[MAXN];
bool SPFA(int start)
{
	memset(vis, false, sizeof(vis));
	memset(dist, 0x3f, sizeof(dist));
	
	vis[start] = true;
	dist[start] = 0;
	queue<int> que;
	
	while (!que.empty())
	que.pop();
	
	que.push(start);
	memset(cnt, 0, sizeof(cnt));
	cnt[start] = 1;
	
	while (!que.empty())
	{
		int u = que.front();
		que.pop();
		vis[u] = false;
		for (int i = 0; i < E[u].size(); i++)
		{
			int v = E[u][i].v;
			if (dist[v] > dist[u] + E[u][i].cost)
			{
				dist[v] = dist[u] + E[u][i].cost;
				if (!vis[v])
				{
					vis[v] = true;
					que.push(v);
					if (++cnt[v] > p)
					{
						return false; // cnt[i]为?入队列列次数,?用来判定是否存在负环回路路
					}
				}
			}
		}
	}
}
int main(){
//	freopen("in.txt","r",stdin);
		while(scanf("%d%d%d",&n,&p,&c)!=EOF){
	
		for(int i=1;i<=n;i++){
			scanf("%d",&mu[i]);
		}
		
		for(int j=0;j<c;j++){
			int st,ed,cost;
			scanf("%d%d%d",&st,&ed,&cost);
			addEdge(st, ed, cost);	
		}
		int sum=INF;
		for(int i=1;i<=p;i++)
		{
			
			SPFA(i);
			int tol=0;
			for(int j=1;j<=n;j++)
			tol+=dist[mu[j]];
			if(sum>tol&&tol!=0)
			sum=tol;
		}
		printf("%d\n",sum);	
	}
	return 0;	
}

阅读更多

没有更多推荐了,返回首页