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 }
  • 相关阅读:
    7-22 朋友圈(25 分)
    c++之函数重载
    c++之函数的其它用法
    c++之引用
    c++之内存模型
    c++实例之通讯录管理系统之清空联系人功能(七)
    c++实例之通讯录管理系统之修改联系人功能(六)
    c++实例之通讯录管理系统之查找联系人功能(五)
    c++实例之通讯录管理系统之删除联系人功能(四)
    c++实例之通讯录管理系统之显示联系人功能(三)
  • 原文地址:https://www.cnblogs.com/SilverNebula/p/6710852.html
Copyright © 2011-2022 走看看