zoukankan      html  css  js  c++  java
  • HDU4889 Scary Path Finding Algorithm

    Fackyyj loves the challenge phase in TwosigmaCrap(TC). One day, he meet a task asking him to find shortest path from vertex 1 to vertex n, in a graph with at most n vertices and m edges. (1 ≤ n ≤ 100,0 ≤ m ≤ n(n-1)) 

    Fackyyj solved this problem at first glance, after that he opened someone's submission, spotted the following code: 

     1 long long spfa_slf() { 
     2 int n,m; 
     3 cin >> n >> m; 
     4 
     5 vector<pair<int,int> > edges111111; 
     6 for(int i = 0;i < m;i++) { 
     7 int x,y,w; 
     8 cin >> x >> y >> w; 
     9  edgesxx.push_back(make_pair(y,w)); 
    10 } 
    11 
    12 deque<int> q; 
    13 vector<long long> dist(n+1, ~0ULL>>1); 
    14 vector<bool> inQueue(n+1, false); 
    15  dist11 = 0; q.push_back(1); inQueue11 = true; 
    16 
    17 int doge = 0; 
    18 while(!q.empty()) { 
    19 int x = q.front(); q.pop_front(); 
    20 if(doge++ > C) { 
    21 puts("doge"); 
    22 return 233; 
    23 } 
    24  for(vector<pair<int,int> >::iterator it = edgesxx.begin(); 
    25  it != edgesxx.end();++it) { 
    26 int y = it->first; 
    27 int w = it->second; 
    28  if(distyy > distxx + w) { 
    29  distyy = distxx + w; 
    30  if(!inQueueyy) { 
    31  inQueueyy = true; 
    32  if(!q.empty() && distyy > distq.front()q.front()) 
    33 q.push_back(y); 
    34 else 
    35 q.push_front(y); 
    36 } 
    37 } 
    38 } 
    39  inQueuexx = false; 
    40 } 
    41  return distnn; 
    42 } 

    Fackyyj's face lit up with an evil smile. He immediately clicked button "Challenge!", but due to a hard disk failure, all of his test case generators were lost! Fackyyj had no interest on recreating his precise generators, so he asked you to write one. The generator should be able to generate a test case with at most 100 vertices, and it must be able to fail the above code, i.e. let the above code print "doge". It should NOT contain any negative-cost loop. 

     For those guys who doesn't know C++, Fackyyj explain the general idea of the above algorithm by the following psuedo-code: 

    InputInput contains several test cases, please process till EOF. 
     For each test case, there will be a single line containing an integer C. It is the constant C in the above code. (C <= 23333333)OutputFor each test case, on the first line, print two integers, n and m, indicating the number of vertices and the number of edges of your graph. Next m lines, on each line print x y w, means there is a road from x to y, cost w. 
    1 ≤ n ≤ 100,0 ≤ m ≤ n(n-1),|w| < 2 31. Note that your output shouldn't contain any negative-cost loop.Sample Input

    1

    Sample Output

    4 3
    1 2 1
    2 3 1
    3 4 1

    图论  愉悦脑洞题 卡SPFA

    给了一个SPFA的SLF优化程序,让你把它卡掉。

    这个SLF的机制大概是每次更新完,如果被更新的点dis比队头dis小,就把它插到队头。

    根据这个性质,只要造出数据让它多出许多遍重复的更新即可

    http://blog.csdn.net/u012221059/article/details/38336633

    ↑这里有张图可以很直观地说明问题。可以发现,随着三角数量的增长,复杂度成指数级上升。

    莫慌,不加这个鬼畜优化的普通SPFA,复杂度上界还是$O(NM)$的

    注释掉的部分可以卡出一定的效果,但是卡不到指数级的样子。

    注意输出顺序也很关键。

    那么问题来了,我为什么要花时间写这么道没意义的破题?

     1 /*by SilverN*/
     2 #include<algorithm>
     3 #include<iostream>
     4 #include<cstring>
     5 #include<cstdio>
     6 #include<cmath>
     7 #include<vector>
     8 using namespace std;
     9 int main(){
    10 //    freopen("in.txt","w",stdout);
    11     int i,j,C;
    12     while(scanf("%d",&C)!=EOF){
    13         int n=61,m=90;
    14 //        int n=99,m=98/2*3;
    15         printf("%d %d
    ",n,m);
    16 /*        for(i=3;i<=n;i+=2){
    17             printf("%d %d %d
    ",i-2,i,-(1<<(i-1)));
    18         }
    19         for(i=1;i<=n-2;i+=2){
    20             printf("%d %d %d
    ",i,i+1,0);
    21         }
    22         for(i=2;i<=n;i+=2){
    23             printf("%d %d %d
    ",i,i+1,-(1<<(i-2)));
    24         }*/
    25         for(i=0;i<30;i++)
    26             printf("%d %d %d
    ",i*2+1,i*2+2,0);
    27         for(i=0;i<30;i++)
    28             printf("%d %d %d
    ",i*2+2,i*2+3,-(1<<(30-i)));
    29         for(i=0;i<30;i++)
    30             printf("%d %d %d
    ",i*2+1,i*2+3,-(1<<(30-i-1))); 
    31     }
    32     return 0;
    33 }
  • 相关阅读:
    Java图片裁剪
    jvm参数
    Druid数据源监控配置
    执行jar包或执行其中的某个类
    十进制和二进制之间的相互转化
    Java位运算
    获取网络资源保存本地
    前端PHP入门-010-内部函数
    前端PHP入门-011-可变函数
    前端PHP入门-009-匿名函数
  • 原文地址:https://www.cnblogs.com/SilverNebula/p/6710852.html
Copyright © 2011-2022 走看看