湫湫系列故事——设计风景线
Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 65535/32768 K (Java/Others)
Total Submission(s): 4293 Accepted Submission(s): 756
Problem Description
随着杭州西湖的知名度的进一步提升,园林规划专家湫湫希望设计出一条新的经典观光线路,根据老板马小腾的指示,新的风景线最好能建成环形,如果没有条件建成环形,那就建的越长越好。
现在已经勘探确定了n个位置可以用来建设,在它们之间也勘探确定了m条可以设计的路线以及他们的长度。请问是否能够建成环形的风景线?如果不能,风景线最长能够达到多少?
其中,可以兴建的路线均是双向的,他们之间的长度均大于0。
现在已经勘探确定了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
接下去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
Source
Recommend
题意中文都看的懂。
判断环容易,就是判断各个连通分支的最大路径不容易,下午懵了一下午,晚上再试试,卡在并查集的路径压缩了!!!!
并查集的路径压缩应该牢记。
代码:608MS 5980K
#include<stdio.h>
#include<queue>
#include<string.h>
using namespace std;
const int MYDD=100000+1103;
int set[MYDD];//并查集的根节点
int edgenum;//边数
int head[MYDD];//节点头指针
int n,m;
void init() {
edgenum=0;
memset(head,-1,sizeof(head));
for(int j=1; j<=n; j++)
set[j]=j;
}
int find(int x) { //查找根节点
while(x!=set[x])
x=set[x];
int child=x;
while(x!=child) {//路径压缩
int t=set[child];//记录当前元素父节点
set[child]=x;//把这里写成 set[x]=child 总是超时
child=t;//把t赋值给当前元素
}
return x;
}
bool combine(int x,int y) {//判断环
int fx=find(x);
int fy=find(y);
if(fx!=fy)//相同的根节点,有环
set[fx]=fy;
else
return true;
return false;
}
struct EDGE {
int u,v,w,next;
} edge[MYDD*2];
void addedge(int u,int v,int w) { //边的增加
EDGE Edge= {u,v,w,head[u]};
edge[edgenum]=Edge;
head[u]=edgenum++;
}
bool vis[MYDD];
bool used[MYDD];//记录节点是否在上一次 BFS 使用
int dis[MYDD];
int temp,Tnode;
void BFS(int sx) {
memset(vis,false,sizeof(vis));
memset(dis,0,sizeof(dis));
queue<int> Q;
vis[sx]=true;
temp=0;
Tnode=sx;
Q.push(sx);
while(!Q.empty()) {
int first=Q.front();
Q.pop();
used[first]=true;
for(int j=head[first]; j!=-1; j=edge[j].next) {
int v=edge[j].v;
if(!vis[v]) {
dis[v]=dis[first]+edge[j].w;
if(dis[v]>temp) {
temp=dis[v];
Tnode=v;
}
vis[v]=true;
Q.push(v);
}
}
}
}
int main() {
while(scanf("%d%d",&n,&m)!=EOF) {
init();
int flag=0;
while(m--) {
int u,v,w;
scanf("%d%d%d",&u,&v,&w);
if(flag)
continue;//已经存在环
addedge(u,v,w);
addedge(v,u,w);
flag=combine(u,v);//判断环
}
if(flag)
puts("YES");
else {
int ans=0;
memset(used, false, sizeof(used));
for(int j=1; j<=n; j++) { //可能是非连通图
if(used[j])
continue;//已经出现在以前BFS查询中
BFS(j);//每个节点都找对应的S-T端点
BFS(Tnode);//找最长路
if(temp>ans)
ans=temp;
}
printf("%d\n", ans);
}
}
return 0;
}
后:
坎坷的 AC 路。。。
**************************************