• POJ3259Wormholes


    转载请注明出处:優YoU  http://user.qzone.qq.com/289065406/blog/1299075341

    提示:

    利用虫洞的时光旅行,很有趣的一道题。涉及到图论的知识,关键是构造图,用Bellman-Ford算法找出负权环

    Bellman-Ford算法核心在于松弛,具体可以百度,这里就不重复前人的智慧了O(∩_∩)O哈哈~

    需要注意的就是输入说明Input这部分,很多人读不懂这段题意:

    正权(双向)边部分:
    Line 1 of each farm: Three space-separated integers respectively: N, M, and W


    Lines 2~M+1 of each farm: Three space-separated numbers (S, E, T) that describe, respectively: a bidirectional path between S and E that requires T seconds to traverse.

    Two fields might be connected by more than one path.

     

    负权(单向)边部分:
    Lines M+2~M+W+1 of each farm: Three space-separated numbers (S, E, T) that describe, respectively: A one way path from S to E that also moves the traveler back T seconds.

     1 //Memory Time 
    2 //308K 204MS
    3
    4 #include<iostream>
    5 using namespace std;
    6
    7 int dis[1001]; //源点到各点权值
    8 const int max_w=10001; //无穷远
    9
    10 class weight
    11 {
    12 public:
    13 int s;
    14 int e;
    15 int t;
    16 }edge[5200];
    17
    18 int N,M,W_h; //N (1≤N≤500)fields 顶点数
    19 //M (1≤M≤2500)paths 正权双向边
    20 //W_h (1≤W≤200) wormholes 虫洞(回溯),负权单向边
    21 int all_e; //边集(边总数)
    22
    23 bool bellman(void)
    24 {
    25 bool flag;
    26
    27 /*relax*/
    28
    29 for(int i=0;i<N-1;i++)
    30 {
    31 flag=false;
    32 for(int j=0;j<all_e;j++)
    33 if(dis[edge[j].e] > dis[edge[j].s] + edge[j].t)
    34 {
    35 dis[edge[j].e] = dis[edge[j].s] + edge[j].t;
    36 flag=true; //relax对路径有更新
    37 }
    38 if(!flag)
    39 break; //只要某一次relax没有更新,说明最短路径已经查找完毕,或者部分点不可达,可以跳出relax
    40 }
    41
    42 /*Search Negative Circle*/
    43
    44 for(int k=0;k<all_e;k++)
    45 if( dis[edge[k].e] > dis[edge[k].s] + edge[k].t)
    46 return true;
    47
    48 return false;
    49 }
    50 int main(void)
    51 {
    52 int u,v,w;
    53
    54 int F;
    55 cin>>F;
    56 while(F--)
    57 {
    58 memset(dis,max_w,sizeof(dis)); //源点到各点的初始值为无穷,即默认不连通
    59
    60 cin>>N>>M>>W_h;
    61
    62 all_e=0; //初始化指针
    63
    64 /*read in Positive Paths*/
    65
    66 for(int i=1;i<=M;i++)
    67 {
    68 cin>>u>>v>>w;
    69 edge[all_e].s=edge[all_e+1].e=u;
    70 edge[all_e].e=edge[all_e+1].s=v;
    71 edge[all_e++].t=w;
    72 edge[all_e++].t=w; //由于paths的双向性,两个方向权值相等,注意指针的移动
    73 }
    74
    75 /*read in Negative Wormholds*/
    76
    77 for(int j=1;j<=W_h;j++)
    78 {
    79 cin>>u>>v>>w;
    80 edge[all_e].s=u;
    81 edge[all_e].e=v;
    82 edge[all_e++].t=-w; //注意权值为负
    83 }
    84
    85 /*Bellman-Ford Algorithm*/
    86
    87 if(bellman())
    88 cout<<"YES"<<endl;
    89 else
    90 cout<<"NO"<<endl;
    91 }
    92 return 0;
    93 }
  • 相关阅读:
    【IT笔试面试题整理】把n个骰子扔在地上,所有骰子朝上一面的点数之和为S概率转
    面试题位操作
    微软面试题 寻找数组中出现的唯一重复的一个数
    【IT笔试面试题整理】给定二叉树先序中序,建立二叉树的递归算法
    【IT笔试面试题整理】 二叉树任意两个节点间最大距离
    面试题堆栈和队列
    LRU cache实现 Java 转
    【IT笔试面试题整理】有序数组生成最小高度二叉树
    Unity3d Asset Store下载的资源在哪?
    Xcode 6 如何将 模拟器(simulator) for iphone/ipad 转变成 simulator for iphone
  • 原文地址:https://www.cnblogs.com/lyy289065406/p/2121604.html
Copyright © 2020-2023  润新知