Heavy Transportation POJ - 1797

题意:有n个城市,m条道路,在每条道路上有一个承载量,现在要求从1到n城市最大承载量,而最大承载量就是从城市1到城市n所有通路上的最大承载量

dijkstra的变形 求最大载重量 

思路:1.初始化条件和dijkstra一样,把起始节点能到到的节点更新为dis[i],起始节点到达不了的节点更新为INF,新增加一个标记数组,除1之外都标记为0,1标记为1,作用是判断该节点是否被使用过.

           2.然后找与1相邻的节点中载重量最大的,记录下来节点位置和最大载重量,该节点不能被使用过。

           3.遍历剩余节点,判断2中节点到达其余节点的最小值(最大输入流而且必须是map[2节点][剩余节点]存在,和dis[剩余节点比较],若大于dis,就更新dis,否则不更新.

          4.再回到第二步,把之前使用过的节点扔掉,继续第三步.


大佬代码:

出处:http://poj.org/showmessage?message_id=354786

原代码最后的判断条件有误,我已修改过来.

#include <cstdio>
#include <iostream>
#include <ctime>
#include <cstring>
#include<cstdlib>
#pragma warning(disable:4996)
using namespace std;
#define MAX 0x7fffffff
#define Min(a, b) ((a) < (b) ? (a) : (b))    
int map[1010][1010], dis[1010];
int mark[1010];
int n, m, s, t, W = 0;
void Dijkstra()
{
	int i, j, k, min;
	for (i = 1; i <= n; i++)
	{
		mark[i] = 0;
		if (map[1][i] != 0)
			dis[i] = map[1][i];
		else
			dis[i] = MAX;
	}//预处理 把1可以到达的节点全都设置成dis[i],到达不了的节点全都设置成MAX
	mark[1] = 1;
	for (i = 1; i < n; i++)//遍历除第一个节点之外的剩下的n-1个节点
	{
		min = 0;//最大权值
		for (j = 1; j <= n; j++)
			if (!mark[j] && dis[j] > min&&dis[j] != MAX)//从1节点引申出来的节点中的最大值
			{
				min = dis[j];
				k = j;//记录下是第几个节点权值最大
			}
		mark[k] = 1;
		for (j = 1; j <= n; j++)//遍历其余的节点
			if (!mark[j])
			{
				int Q;
				Q = Min(dis[k], map[k][j]);//Q表示从起始节点到该节点的值和从该节点到目标节点的最小值
				//Q表示走1-k-j这条路的最大限流
				if ((dis[j]<Q||dis[j]==MAX)&&map[k][j] != 0)//如果最大限流大于1-j节点,且k-j有路,更新dis[j]的值
				{
					dis[j] = Q;
				}
			}
	}
	printf("Scenario #%d:\n%d\n\n", W, dis[n]);
}
int main()
{
	int i, j, x, y, d, N;
	scanf("%d", &N);
	while (N--)
	{
		scanf("%d %d", &n, &m);
		W++;
		memset(map, 0, sizeof(map));


		for (i = 1; i <= m; i++)
		{
			scanf("%d %d %d", &x, &y, &d);
			map[x][y] = map[y][x] = d;
		}
		Dijkstra();
	}
}

我的代码:

扫描二维码关注公众号,回复: 2715535 查看本文章

用的是优先队列去优化

#include <iostream>   
#include <algorithm>   
#include <cstdio>   
#include <cstring>  
#include<cmath>  
#include<cstdlib>  
#include<map>  
#include<string>  
#include<vector>  
#include<queue>  
#include<functional>  
#pragma warning(disable:4996)  
//最大边的最小权值  
using namespace std;
typedef long long ll;
const int INF = 999999999;
int n, m;
typedef pair<int, int> P;//第一个值表示最大权值  
struct edge {
	int to, cost;
};
int mn;
int d[1001];
vector<edge>G[1005];
int vis[1005];
void dijkstra(int s)
{
	priority_queue<P, vector< P >, less< P > >que;
	for (int i = 1; i <= n; i++)d[i] = INF;
	memset(vis, 0, sizeof(vis));
	d[s] = 0;
	vis[s] = 1;
	que.push(P(0, s));
	mn = 0;
	while (!que.empty())
	{
		P p = que.top();
		que.pop();
		int v = p.second;
		if (d[v] >p.first)continue;
		for (int i = 0; i < G[v].size(); i++)
		{
			edge e = G[v][i];
			if (d[v] == 0)
			{
				d[e.to] = e.cost;
				que.push(P(d[e.to], e.to));
				continue;
			}
			vis[v] = 1;
			if (!vis[e.to])
			{
				int mn = min(d[v], e.cost);
				if ((mn > d[e.to] || d[e.to] == INF))
				{
					d[e.to] = mn;
					que.push(P(d[e.to], e.to));
				}
			}
		}
	}


}
int main()
{
	int T;
	scanf("%d", &T);
	int i, j, k;
	int icase = 0;
	while (T--)
	{
		scanf("%d%d", &n, &m);
		for (i = 1; i <= n; i++)G[i].clear();
		for (i = 1; i <= m; i++)
		{
			int x, y, z;
			scanf("%d%d%d", &x, &y, &z);
			edge e;
			e.to = x, e.cost = z;
			G[y].push_back(e);
			edge ee;
			ee.to = y, ee.cost = z;
			G[x].push_back(ee);
		}
		dijkstra(1);
		printf("Scenario #%d:", ++icase);
		printf("\n");
		printf("%d\n\n", d[n]);
	}
}


猜你喜欢

转载自blog.csdn.net/qq_17175221/article/details/80395101