hdu 3721
来源:互联网 发布:四十不惑 五十而知天命 编辑:程序博客网 时间:2024/05/13 16:55
借鉴了网上一个大牛的代码
#include <cstdio>#include <cstring>#include <algorithm>using namespace std;const int MAXN = 2500 + 123;struct EDGE{ int v, val, next; bool flag;}edge[MAXN * 2];int cnt = 0;int head[MAXN];int dis[MAXN];int pre[MAXN];bool vis[MAXN];int q[MAXN];void addedge(int x, int y, int z){ edge[cnt].v = y; edge[cnt].val = z; edge[cnt].flag = true; edge[cnt].next = head[x]; head[x] = cnt++;}int dfs(int src, int& rmin){ memset(dis, -1, sizeof(dis)); int front = 0; int rear = 0; q[rear++] = src; dis[src] = 0; int id = src; while(front < rear)//找出直径的一端 { int now = q[front++]; for(int p = head[now]; p != -1; p = edge[p].next) { if(!edge[p].flag) continue;//删除的边 int v = edge[p].v; if(dis[v] != -1) continue; dis[v] = dis[now] + edge[p].val; q[rear++] = v; if(dis[v] > dis[id]) { id = v; } } } front = rear = 0; src = id; q[rear++] = src; dis[src] = 0; id = src; vis[src] = true; while(front < rear) { int now = q[front++]; for(int p = head[now]; p != -1; p = edge[p].next) { if(!edge[p].flag) continue;//删除的边 int v = edge[p].v; if(vis[v]) continue; dis[v] = dis[now] + edge[p].val; pre[v] = now; q[rear++] = v; vis[v] = true; if(dis[v] > dis[id]) { id = v; } } } int half = dis[id] / 2; int small = dis[id]; rmin = 0; for(int i = id; i != src; i = pre[i])//找到那个根节点 { if(dis[i] >= half && dis[pre[i]] <= half) { rmin=min(dis[i],small-dis[pre[i]]); break; } } return small;}int main(){ int T; int n; int x, y, z; scanf("%d", &T); for(int cas = 1; cas <= T; cas++) { scanf("%d", &n); if(n == 1) { printf("Case %d: 0\n",cas); continue; } cnt = 0; memset(head, -1, sizeof(head)); for(int i = 1; i < n; i++) { scanf("%d%d%d", &x, &y, &z); addedge(x, y, z); addedge(y, x, z); } //开始枚举删边 int a, b, c, d; int ans = 1 << 30; for(int i = 0; i < cnt; i+=2) //注意加2不是加1 { edge[i].flag = false; edge[i ^ 1].flag = false; memset(vis, 0, sizeof(vis)); for(int j = 0; j < n; j++) if(!vis[j]) { a = dfs(j, c);//a是这个部分的直径,c是这个部分选定的使最长路最短的根节点发出的最长路 break; } for(int j = 0; j < n; j++) if(!vis[j]) { b = dfs(j, d); break; } int rmax = max(a, b); rmax = max(rmax, c + d + edge[i].val); if(rmax < ans) ans = rmax; edge[i].flag = true; edge[i ^ 1].flag = true; } printf("Case %d: %d\n", cas, ans); } return 0;}
- hdu 3721
- HDU 3721
- HDU 3721 Building Roads
- HDU 3721 Building Roads
- hdu
- hdu
- HDU
- hdu ()
- hdu
- hdu
- HDU
- HDU
- hdu
- hdu
- HDU
- Hdu
- hdu
- hdu-
- Commercial Internet Protocol Security Option
- 关于最多只能选择两个多选框的jQuery功能实现
- android Notification 的使用
- SystemProperties的native code 目录
- Django调用JS、CSS、图片等静态文件
- hdu 3721
- 人 之 将 老
- 各种编码之间的转换
- 无题
- Re: Defining a boolean dimension attribute in SSAS 2005
- 在PL/SQL中如何实现.NET的String.Format功能
- 总结一些Java问题
- 白话经典算法系列之四 直接选择排序及交换二个数据的正确实现
- 经验累积