[C] 2013腾讯马拉松初赛 ACM 湫湫系列故事——设计风景线 →→→→→进入此内容的聊天室

来自 , 2020-08-16, 写在 C, 查看 170 次.
URL http://www.code666.cn/view/da4902cb
  1. /*
  2.  
  3. 2013腾讯马拉松初赛第2场
  4.  
  5. 1005 湫湫系列故事——设计风景线
  6. ________________________________________
  7. Time Limit: 3 Seconds   Memory Limit: 65536K
  8. ________________________________________
  9.  
  10. 随着杭州西湖的知名度的进一步提升,园林规划专家湫湫希望设计出一条新的经典观光线路,根据老板马小腾的指示,新的风景线最好能建成环形,如果没有条件建成环形,那就建的越长越好。
  11. 现在已经勘探确定了n个位置可以用来建设,在它们之间也勘探确定了m条可以设计的路线以及他们的长度。请问是否能够建成环形的风景线?如果不能,风景线最长能够达到多少?
  12. 其中,可以兴建的路线均是双向的,他们之间的长度均大于0。
  13.  
  14. Input
  15.  
  16. 测试数据有多组,每组测试数据的第一行有两个数字n, m,其含义参见题目描述;
  17. 接下去m行,每行3个数字u v w,分别代表这条线路的起点,终点和长度。
  18.  
  19. [Technical Specification]
  20. 1. n<=100000  
  21. 2. m <= 1000000
  22. 3. 1<= u, v <= n
  23. 4. w <= 1000
  24.  
  25. Output
  26.  
  27. 对于每组测试数据,如果能够建成环形(并不需要连接上去全部的风景点),那么输出YES,否则输出最长的长度,每组数据输出一行。
  28.  
  29. Sample Input
  30.  
  31. 3 3
  32. 1 2 1
  33. 2 3 1
  34. 3 1 1
  35.  
  36. Sample Output
  37.  
  38. YES
  39.  
  40. */
  41.  
  42. /*
  43. 解题报告:
  44. 首先做这题的时候很纠结,不知道题目中说的环形是什么,是要所有的路都用上还是怎么样。经过一番思考后,觉得应该是判环。
  45. 我就直接想到了双联通分量了。至于最长路,就是如果不存在双联通分量的情况,必然是几棵树了。就是求一下树的直径。
  46. 经过一番YY之后,就开始写了。
  47.  
  48. 先求双联通,然后再BFS,求树直径。交上去之后RE掉了,当时也不确定自己算法正确性,有想过要用加栈的方法。可是没去试。后来和别人讨论了,他让我加了,结果就这么过了。
  49. 我看到别人的代码这么短的。
  50. 我看了别人的做法原来他们是用并查集来判环的。学习了。
  51. PS:以后递归溢出要加#pragma comment(linker, "/STACK:36777216")//开大点
  52. 栈这个试试。
  53. */
  54.  
  55. #include<string.h>
  56. #include<map>
  57. #include<algorithm>
  58. #include<math.h>
  59. #include<stdio.h>
  60. #pragma comment(linker, "/STACK:36777216")//开大点栈
  61. using namespace std;
  62. const int MAX = 1100000 * 2;
  63.  
  64. const double EPS = 1.0e-8;
  65. bool dblcmp(double x) {
  66.     if(fabs(x) < EPS)return 0;
  67.     return x < 0 ? -1 : 1;
  68. }
  69.  
  70. const int MAXN = 110000;
  71. const int MAXM = 1100000 * 2;
  72. struct EDGE {
  73.     int v, next, d;
  74. } edge[MAXM];
  75. int E;
  76. int  com[MAXN], DN, CN, h[MAXN], d[MAXN], stk[MAXN], top;
  77. int head[MAXN];
  78. void  DFS(int  t, int f) {
  79.     int  i, ed;
  80.     stk[top++] = t;
  81.     d[t] = DN--;
  82.     h[t] = d[t];
  83.     for(i = head[t]; i != -1; i = edge[i].next) {
  84.         ed = edge[i].v;
  85.         if(ed != f) {
  86.             if(d[ed] == 0) {
  87.                 DFS(ed, t);
  88.                 if(h[ed] > h[t]) h[t] = h[ed];
  89.             }
  90.             if(com[ed] == 0 && h[t] < d[ed])
  91.                 h[t] = d[ed];
  92.         }
  93.     }
  94.     if(h[t] == d[t]) {
  95.         com[t] = ++CN;
  96.         while(stk[top - 1] != t) {
  97.             com[stk[top - 1]] = CN;
  98.             top--;
  99.         }
  100.         top--;
  101.     }
  102. }
  103.  
  104. void SCC(int N) {
  105.     int  i;
  106.     CN = 0;
  107.     DN = N;
  108.     top = 0;
  109.     memset(com, 0, sizeof(int) * (N + 2));
  110.     memset(h, 0, sizeof(int) * (N + 2));
  111.     memset(d, 0, sizeof(int) * (N + 2));
  112.     for(i = 1; i <= N; i++) {
  113.         if(com[i] == 0)
  114.             DFS(i, -1);
  115.     }
  116. }
  117. void add(int s, int t, int d) {
  118.     edge[E].v = t;
  119.     edge[E].d = d;
  120.     edge[E].next = head[s];
  121.     head[s] = E++;
  122. }
  123. typedef __int64 lld;
  124. int vis[MAXN];
  125. int q[MAXN];
  126. int dis[MAXN];
  127. map<lld, int>mp;
  128. int BFS(int s, int CS, int &ans) {
  129.     int rear = 0, front = -1;
  130.     int i, v;
  131.     dis[s] = 0;
  132.     vis[s] = CS;
  133.     q[0] = s;
  134.     while(rear != front) {
  135.         front++;
  136.         s = q[front];
  137.         for(i = head[s]; i != -1; i = edge[i].next) {
  138.             v = edge[i].v;
  139.             if(vis[v] == CS)continue;
  140.             dis[v] = edge[i].d + dis[s];
  141.             vis[v] = CS;
  142.             rear++;
  143.             q[rear] = v;
  144.         }
  145.     }
  146.     int ind = s;
  147.     int tmp = dis[s];
  148.     for(i = 1; i <= rear; i++) {
  149.         v = q[i];
  150.         if(dis[v] > tmp) {
  151.             tmp = dis[v];
  152.             ind = v;
  153.         }
  154.     }
  155.     if(tmp > ans)ans = tmp;
  156.     return ind;
  157. }
  158. bool dig(char x) {
  159.     return x >= '0' && x <= '9';
  160. }
  161. int getval() {
  162.     int ret = 0, sign = 1;
  163.     char c;
  164.     while(!dig(c = getchar()) && c != '-');
  165.     if(c == '-')sign = -1;
  166.     else ret = c - '0';
  167.     while(dig(c = getchar()))ret = ret * 10 + c - '0';
  168.     return ret * sign;
  169. }
  170. int main() {
  171.     int i, n, m, j;
  172.     int k, CS = 1;
  173.     while(scanf("%d%d", &n, &m) != EOF) {
  174.         //mp.clear();
  175.         memset(head, -1, sizeof(int) * (n + 5));
  176.         E = 0;
  177.         bool flag = false;
  178.         while(m--) {
  179.             //scanf("%d%d%d",&i,&j,&k);
  180.             i = getval();
  181.             j = getval();
  182.             k = getval();
  183.             if(i == j)continue; //
  184.             //if(i>j)swap(i,j);
  185.             //lld tmp=(lld)(i)*(lld)(1000000)+(lld)(j);
  186.             //mp[tmp]++;
  187.             //if(mp[tmp]>1)flag=true;
  188.             add(i, j, k);
  189.             add(j, i, k);
  190.  
  191.         }
  192.         if(flag) {
  193.             puts("YES");
  194.             continue;
  195.         }
  196.         CS++;
  197.         SCC(n);
  198.         //printf("CN=%d\n",CN);
  199.         if(CN != n) {
  200.             puts("YES");
  201.             continue;
  202.         }
  203.  
  204.         memset(vis, -1, sizeof(int) * (n + 2));
  205.         int ans = 0;
  206.         int tmp, j;
  207.         for(i = 1; i <= n; i++) {
  208.             if(vis[i] == -1) {
  209.                 j = BFS(i, CS, ans);
  210.                 CS++;
  211.  
  212.                 j = BFS(j, CS, ans);
  213.                 CS++;
  214.             }
  215.         }
  216.  
  217.         printf("%d\n", ans);
  218.     }
  219.     return 0;
  220. }

回复 "2013腾讯马拉松初赛 ACM 湫湫系列故事——设计风景线"

这儿你可以回复上面这条便签

captcha