您的位置:首页 > 其它

pku 1797 Heavy Transportation 分支界限法

2010-09-01 19:40 274 查看
题目

http://acm.pku.edu.cn/JudgeOnline/problem?id=1797



分支界限法,学好了很强大.ps,第一次用优先队列...



#include <stdio.h>
#include <queue>
using namespace std;

#define max 1001
#define MIN(x,y)(x < y ? x : y)

int map[max][max];
int dist[max];
//前驱节点
int pre[max];

int n,m;

struct HeapNode{
	int i;//顶点
	int d;//从源点到i的当前路径上的最小权值
	HeapNode(int i = 0,int d = 0){
		this->i = i;
		this->d = d;
	}
	friend bool operator < (HeapNode a,HeapNode b){
		return a.d < b.d;
	}
};

//dist[i]:从源点到i的多条路径中每条路径上权值最小的边这一集合中的最大值
//常规标记dijkstra法:dist[i] = max(dist[i],min(d[k],map[k][i]));
//分支界限法:dist[i] = max(dist[i],min(enode(i == k).d,map[k][i]));
void dijkstra(int u){
	memset(pre,0,sizeof(pre));
	memset(dist,0,sizeof(dist));
	
	HeapNode node,enode;
	priority_queue<HeapNode> p_q;
	
	enode.i = u;
	enode.d = 0;
	p_q.push(enode);
	
	//先多加几个节点进去是因为控制约束在根节点不起作用...
	for(int j = 1;j <= n;j++)
		if(map[enode.i][j]){
			node.i = j;
			node.d = map[enode.i][j];
			p_q.push(node);
		}
		
	while(!p_q.empty()){
		enode = p_q.top();
		p_q.pop();
		//搜索问题的解空间
		for(int j = 1;j <= n;j++)
			//控制约束:经过顶点i到顶点j的该条路径上的最小权值大于目前到顶点j的所有路径上最小值的最大值
			if(map[enode.i][j] && MIN(enode.d,map[enode.i][j]) > dist[j]){
				dist[j] = MIN(enode.d,map[enode.i][j]);
				pre[j] = enode.i;
				node.i = j;
				node.d = dist[j];
				p_q.push(node);
			}
	}
}

int main(){
	//freopen("data.txt","r",stdin);
	int _case,__case = 0;
	scanf("%d",&_case);
	while(++__case <= _case){
		memset(map,0,sizeof(map));
		scanf("%d%d",&n,&m);
		int i;
		int s,e,w;
		for(i = 1;i <= m;i++){
			scanf("%d%d%d",&s,&e,&w);
			map[s][e] = w;
			map[e][s] = w;
		}
		dijkstra(1);
		printf("Scenario #%d:/n%d/n/n",__case,dist
);
	}
	return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: