用户注册



邮箱:

密码:

用户登录


邮箱:

密码:
记住登录一个月忘记密码?

发表随想


还能输入:200字
云代码 - c代码库

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

2013-03-25 作者: 小蜜锋举报

[c]代码库

/*

2013腾讯马拉松初赛第2场

1005 湫湫系列故事——设计风景线
________________________________________
Time Limit: 3 Seconds   Memory Limit: 65536K
________________________________________

随着杭州西湖的知名度的进一步提升,园林规划专家湫湫希望设计出一条新的经典观光线路,根据老板马小腾的指示,新的风景线最好能建成环形,如果没有条件建成环形,那就建的越长越好。
现在已经勘探确定了n个位置可以用来建设,在它们之间也勘探确定了m条可以设计的路线以及他们的长度。请问是否能够建成环形的风景线?如果不能,风景线最长能够达到多少?
其中,可以兴建的路线均是双向的,他们之间的长度均大于0。

Input

测试数据有多组,每组测试数据的第一行有两个数字n, m,其含义参见题目描述;
接下去m行,每行3个数字u v w,分别代表这条线路的起点,终点和长度。

[Technical Specification]
1. n<=100000  
2. m <= 1000000
3. 1<= u, v <= n 
4. w <= 1000

Output

对于每组测试数据,如果能够建成环形(并不需要连接上去全部的风景点),那么输出YES,否则输出最长的长度,每组数据输出一行。

Sample Input

3 3
1 2 1
2 3 1
3 1 1

Sample Output

YES

*/

/*
解题报告:
首先做这题的时候很纠结,不知道题目中说的环形是什么,是要所有的路都用上还是怎么样。经过一番思考后,觉得应该是判环。
我就直接想到了双联通分量了。至于最长路,就是如果不存在双联通分量的情况,必然是几棵树了。就是求一下树的直径。
经过一番YY之后,就开始写了。

先求双联通,然后再BFS,求树直径。交上去之后RE掉了,当时也不确定自己算法正确性,有想过要用加栈的方法。可是没去试。后来和别人讨论了,他让我加了,结果就这么过了。
我看到别人的代码这么短的。
我看了别人的做法原来他们是用并查集来判环的。学习了。
PS:以后递归溢出要加#pragma comment(linker, "/STACK:36777216")//开大点
栈这个试试。
*/

#include<string.h>
#include<map>
#include<algorithm>
#include<math.h>
#include<stdio.h>
#pragma comment(linker, "/STACK:36777216")//开大点栈
using namespace std;
const int MAX = 1100000 * 2;

const double EPS = 1.0e-8;
bool dblcmp(double x) {
    if(fabs(x) < EPS)return 0;
    return x < 0 ? -1 : 1;
}

const int MAXN = 110000;
const int MAXM = 1100000 * 2;
struct EDGE {
    int v, next, d;
} edge[MAXM];
int E;
int  com[MAXN], DN, CN, h[MAXN], d[MAXN], stk[MAXN], top;
int head[MAXN];
void  DFS(int  t, int f) {
    int  i, ed;
    stk[top++] = t;
    d[t] = DN--;
    h[t] = d[t];
    for(i = head[t]; i != -1; i = edge[i].next) {
        ed = edge[i].v;
        if(ed != f) {
            if(d[ed] == 0) {
                DFS(ed, t);
                if(h[ed] > h[t]) h[t] = h[ed];
            }
            if(com[ed] == 0 && h[t] < d[ed])
                h[t] = d[ed];
        }
    }
    if(h[t] == d[t]) {
        com[t] = ++CN;
        while(stk[top - 1] != t) {
            com[stk[top - 1]] = CN;
            top--;
        }
        top--;
    }
}

void SCC(int N) {
    int  i;
    CN = 0;
    DN = N;
    top = 0;
    memset(com, 0, sizeof(int) * (N + 2));
    memset(h, 0, sizeof(int) * (N + 2));
    memset(d, 0, sizeof(int) * (N + 2));
    for(i = 1; i <= N; i++) {
        if(com[i] == 0)
            DFS(i, -1);
    }
}
void add(int s, int t, int d) {
    edge[E].v = t;
    edge[E].d = d;
    edge[E].next = head[s];
    head[s] = E++;
}
typedef __int64 lld;
int vis[MAXN];
int q[MAXN];
int dis[MAXN];
map<lld, int>mp;
int BFS(int s, int CS, int &ans) {
    int rear = 0, front = -1;
    int i, v;
    dis[s] = 0;
    vis[s] = CS;
    q[0] = s;
    while(rear != front) {
        front++;
        s = q[front];
        for(i = head[s]; i != -1; i = edge[i].next) {
            v = edge[i].v;
            if(vis[v] == CS)continue;
            dis[v] = edge[i].d + dis[s];
            vis[v] = CS;
            rear++;
            q[rear] = v;
        }
    }
    int ind = s;
    int tmp = dis[s];
    for(i = 1; i <= rear; i++) {
        v = q[i];
        if(dis[v] > tmp) {
            tmp = dis[v];
            ind = v;
        }
    }
    if(tmp > ans)ans = tmp;
    return ind;
}
bool dig(char x) {
    return x >= '0' && x <= '9';
}
int getval() {
    int ret = 0, sign = 1;
    char c;
    while(!dig(c = getchar()) && c != '-');
    if(c == '-')sign = -1;
    else ret = c - '0';
    while(dig(c = getchar()))ret = ret * 10 + c - '0';
    return ret * sign;
}
int main() {
    int i, n, m, j;
    int k, CS = 1;
    while(scanf("%d%d", &n, &m) != EOF) {
        //mp.clear();
        memset(head, -1, sizeof(int) * (n + 5));
        E = 0;
        bool flag = false;
        while(m--) {
            //scanf("%d%d%d",&i,&j,&k);
            i = getval();
            j = getval();
            k = getval();
            if(i == j)continue; //
            //if(i>j)swap(i,j);
            //lld tmp=(lld)(i)*(lld)(1000000)+(lld)(j);
            //mp[tmp]++;
            //if(mp[tmp]>1)flag=true;
            add(i, j, k);
            add(j, i, k);

        }
        if(flag) {
            puts("YES");
            continue;
        }
        CS++;
        SCC(n);
        //printf("CN=%d\n",CN);
        if(CN != n) {
            puts("YES");
            continue;
        }

        memset(vis, -1, sizeof(int) * (n + 2));
        int ans = 0;
        int tmp, j;
        for(i = 1; i <= n; i++) {
            if(vis[i] == -1) {
                j = BFS(i, CS, ans);
                CS++;

                j = BFS(j, CS, ans);
                CS++;
            }
        }

        printf("%d\n", ans);
    }
    return 0;
}


网友评论    (发表评论)


发表评论:

评论须知:

  • 1、评论每次加2分,每天上限为30;
  • 2、请文明用语,共同创建干净的技术交流环境;
  • 3、若被发现提交非法信息,评论将会被删除,并且给予扣分处理,严重者给予封号处理;
  • 4、请勿发布广告信息或其他无关评论,否则将会删除评论并扣分,严重者给予封号处理。


扫码下载

加载中,请稍后...

输入口令后可复制整站源码

加载中,请稍后...