湫湫系列故事——设计风景线
Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 65535/32768 K (Java/Others)
Total Submission(s): 5018 Accepted Submission(s): 932
Problem Description
随着杭州西湖的知名度的进一步提升,园林规划专家湫湫希望设计出一条新的经典观光线路,根据老板马小腾的指示,新的风景线最好能建成环形,如果没有条件建成环形,那就建的越长越好。
现在已经勘探确定了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
#include
#include
#include
#include
#include
#include
#define maxn 100010
#define inf 0x3f3f3f3f3f3f
using namespace std;
int head[maxn];
int cnt=0;
int ans;
int n,m;
int s,t;
int pre[maxn];
int mark[maxn];
int dist[maxn];
int vis[maxn];
int fr(int x)
{
if(x==pre[x])return x;
int r=fr(pre[x]);
return pre[x]=r;
}
bool join(int x,int y)
{
int r1=fr(x);
int r2=fr(y);
if(r1==r2)return true;
pre[r1]=r2;
return false;
}
struct Node
{
int fr,to,l,next;
}e[maxn*20];
void add(int a,int b,int c)
{
e[cnt].fr=a;
e[cnt].to=b;
e[cnt].l=c;
e[cnt].next=head[a];
head[a]=cnt++;
}
void init()
{
memset(head,-1,sizeof(head));
cnt=0;
ans=-1;
memset(mark,0,sizeof(mark));
for(int i=1;i<=n;i++)pre[i]=i;
}
void bfs(int st)
{
memset(vis,0,sizeof(vis));
memset(dist,0,sizeof(dist));
queue<int>q;
q.push(st);vis[st]=1;dist[st]=0;
while(!q.empty() )
{
int u=q.front() ;
q.pop() ;
for(int i=head[u];i!=-1;i=e[i].next )
{
int v=e[i].to ;
if(!vis[v])
{
if(dist[v]1;
q.push(v);
}
}
}
ans=0;
for(int i=1;i<=n;i++)
{
if(ansint main()
{
int a,b,c;
int root=0;
bool flag=false;
while(scanf("%d%d",&n,&m)!=EOF)
{
init();
flag=false;
for(int i=0;iscanf("%d%d%d",&a,&b,&c);
if(!flag)
{
add(a,b,c);
add(b,a,c);
if(join(a,b))flag=true;
}
}
if(flag)
{
printf("YES\n");
}
else
{
for(int i=1;i<=n;i++)
{
int r=fr(i);
if(!mark[r])
{
mark[r]=1;
bfs(r);
bfs(s);
}
}
printf("%d\n",ans);
}
}
return 0;
}