Time Limit: 1000MS | Memory Limit: 65536K | |
Total Submissions: 28333 | Accepted: 9208 |
Description
Input
Output
Sample Input
2 0 0 3 4 3 17 4 19 4 18 5 0
Sample Output
Scenario #1 Frog Distance = 5.000 Scenario #2 Frog Distance = 1.414
刚开始不会做,看了网上的提示的后说是这是Dijkstra的变种,然后还风轻云淡的说更新条件变一下就行了,结果这句话坑大了,严格来说这就不是Dijkstra!
Dijkstra维护的是两个集合,加入到S集合之中的点已经确定正确,无需再计算,但是这题不一样,就因为这点WA了十多发。关于原算法中S里的点已经正确的证明移步我前一篇博文,但是对于这题用,同样的证明方法,得不出S里的点已经正确的结论。
首先假设S中的点已经最优,而且假设即将加入S的点u没有最优,那么存在一条路径 S里的点 + 任意一点 -> u 是最优的。
那么,如果此任意点属于S,因为维护小顶堆,所以下一个确实应该讲u加入,此处无矛盾。
然后,如果此任意点不属于S,那么就存在两种情况,要么D[s]>D[u],要么D[s]<D[u],但是两种情况都可以成立,也即是说这条假设的路径是可以存在的!
所以,将算法里对S的集合维护取消就对了,只是这还算迪杰斯特拉么?稍后补上另外几种算法的代码。
1 #include <iostream> 2 #include <cmath> 3 #include <cstdio> 4 #include <vector> 5 #include <queue> 6 using namespace std; 7 8 const int SIZE = 205; 9 const int INF = 0x6fffffff; 10 int N; 11 int TEMP[SIZE][2]; 12 double D[SIZE]; 13 bool S[SIZE]; 14 struct Comp 15 { 16 bool operator ()(int & a,int & b) 17 { 18 return D[a] > D[b]; 19 } 20 }; 21 struct Node 22 { 23 int vec; 24 double cost; 25 }; 26 vector<Node> G[SIZE]; 27 28 double dis(int x_1,int y_1,int x_2,int y_2); 29 void dijkstra(int); 30 int main(void) 31 { 32 int count = 0; 33 Node temp; 34 35 while(scanf("%d",&N) && N) 36 { 37 for(int i = 1;i <= N;i ++) 38 scanf("%d%d",&TEMP[i][0],&TEMP[i][1]); 39 for(int i = 1;i <= N;i ++) 40 G[i].clear(); 41 for(int i = 1;i <= N;i ++) 42 for(int j = i + 1;j <= N;j ++) 43 { 44 temp.vec = j; 45 temp.cost = dis(TEMP[i][0],TEMP[i][1],TEMP[j][0],TEMP[j][1]); 46 G[i].push_back(temp); 47 temp.vec = i; 48 G[j].push_back(temp); 49 } 50 51 dijkstra(1); 52 printf("Scenario #%d\n",++ count); 53 printf("Frog Distance = %.3f\n",D[2]); 54 puts(""); 55 } 56 57 return 0; 58 } 59 60 double dis(int x_1,int y_1,int x_2,int y_2) 61 { 62 return sqrt(pow((double)x_1 - x_2,2) + pow((double)y_1 - y_2,2)); 63 } 64 65 void dijkstra(int s) 66 { 67 fill(D,D + SIZE,INF); 68 fill(S,S + SIZE,false); 69 D[s] = 0; 70 priority_queue<int,vector<int>,Comp> que; 71 que.push(s); 72 73 while(!que.empty()) 74 { 75 int cur = que.top(); 76 que.pop(); 77 if(cur == 2) 78 break; 79 /*S[cur] = true; 注释部分即为原Dij应有的部分,此题要移除,加上即WA*/ 80 81 for(int i = 0;i < G[cur].size();i ++) 82 if(/*!S[G[cur][i].vec] && */D[G[cur][i].vec] > max(G[cur][i].cost,D[cur])) 83 { 84 D[G[cur][i].vec] = max(G[cur][i].cost,D[cur]); 85 que.push(G[cur][i].vec); 86 } 87 } 88 }
#include <iostream> #include <queue> #include <cstdio> #include <cmath> using namespace std; const int INF = 0x6fffffff; const int SIZE = 205; int N; double D[SIZE]; struct Node { int vec; double cost; }; struct { int x,y; }TEMP[SIZE]; vector<Node> G[SIZE]; double dis(int,int,int,int); void SPFA(int); int main(void) { Node temp; int count = 0; while(scanf("%d",&N) && N) { for(int i = 1;i <= N;i ++) scanf("%d%d",&TEMP[i].x,&TEMP[i].y); for(int i = 1;i <= N;i ++) G[i].clear(); for(int i = 1;i <= N;i ++) for(int j = i + 1;j <= N;j ++) { temp.vec = j; temp.cost = dis(TEMP[i].x,TEMP[i].y,TEMP[j].x,TEMP[j].y); G[i].push_back(temp); temp.vec = i; G[j].push_back(temp); } SPFA(1); printf("Scenario #%d\n",++ count); printf("Frog Distance = %.3f\n",sqrt(D[2])); puts(""); } return 0; } double dis(int x_1,int y_1,int x_2,int y_2) { return pow((double)x_1 - x_2,2) + pow((double)y_1 - y_2,2); } void SPFA(int s) { queue<int> que; fill(D,D + SIZE,INF); D[s] = 0; que.push(s); while(!que.empty()) { int cur = que.front(); que.pop(); for(int i = 0;i < G[cur].size();i ++) if(D[G[cur][i].vec] > max(D[cur],G[cur][i].cost)) { D[G[cur][i].vec] = max(D[cur],G[cur][i].cost); que.push(G[cur][i].vec); } } }