题目
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[n]); } return 0; }