对于一个菜鸡来说,看到题目没有任何思路...心情复杂.jpg
后来查了查,发现是求树的直径,主要看的方法是两遍DFS。
然后自己写了一段代码出来,只过了75%,如下:
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<math.h>
#include<iostream>
#include<algorithm>
using namespace std;
const int INF=0x3f3f3f3f;
const int MAX=1005;
int n,m;//顶点,边
int a[MAX][MAX];
bool vis[MAX];
int d[MAX];
void dfs(int x)
{
for(int i=0;i<n;i++)
{
if(a[x][i]!=0&&a[x][i]!=INF&&!vis[i])
{
//cout<<"x="<<x<<" i="<<i<<" a[x][i]="<<a[x][i];
vis[i]=true;
d[i]=d[x]+a[x][i];
//cout<<" d[i]="<<d[i]<<endl;
dfs(i);
//vis[i]=false;
}
}
}
int main()
{
scanf("%d",&n);
m=n-1;
for(int i=0;i<n;i++)
{
for(int j=0;j<n;j++)
a[i][j]=INF;
a[i][i]=0;
}
int u,v,dis;
for(int i=0;i<m;i++)
{
scanf("%d%d%d",&u,&v,&dis);
u--,v--;
a[u][v]=a[v][u]=dis;
}
//第一遍dfs
memset(vis,false,sizeof(vis));
memset(d,0,sizeof(d));
vis[0]=true;
dfs(0);
int pos=-1;
int ma=-1;
for(int i=0;i<n;i++)
if(d[i]>ma)
{
ma=d[i];
pos=i;
}
//cout<<endl<<"pos="<<pos<<" max="<<ma<<endl;
//第二遍dfs
memset(vis,false,sizeof(vis));
memset(d,0,sizeof(d));
ma=-1;
vis[pos]=true;
dfs(pos);
for(int i=0;i<n;i++)
if(d[i]>ma)
{
ma=d[i];
pos=i;
}
//cout<<endl<<"pos="<<pos<<" max="<<ma<<endl;
int ans=ma*10+(ma+1)*ma/2;
printf("%d",ans);
return 0;
}
后来看了博客:https://blog.csdn.net/wlxsq/article/details/50815386
才发现错误的根源是题目没有详细的说明数据的范围,虽然报RE,但很大的可能是是数组越界。
最后一组n为10000,二维数组开不了这么大,只能学着用vector了...(第一次用emmmm)
以下是100%正确代码:
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<math.h>
#include<iostream>
#include<algorithm>
#include<vector>
using namespace std;
const int INF=0x3f3f3f3f;
const int MAX=10005;
int n;
struct node
{
int to;
int dis;
};
vector<node>a[MAX];
bool vis[MAX];
int d[MAX];
void dfs(int x)
{
for(int i=0;i<a[x].size();i++)
{
node p=a[x][i];
if(!vis[p.to]&&p.dis)
{
vis[p.to]=true;
d[p.to]=d[x]+p.dis;
dfs(p.to);
}
}
}
int main()
{
scanf("%d",&n);
int u,v,dis;
for(int i=0;i<n;i++)
a[i].clear();
node p;
for(int i=0;i<n-1;i++)
{
scanf("%d%d%d",&u,&v,&dis);
u--,v--;
p.to=v;
p.dis=dis;
a[u].push_back(p);
p.to=u;
a[v].push_back(p);
}
//第一遍dfs
memset(vis,false,sizeof(vis));
memset(d,0,sizeof(d));
vis[0]=true;
dfs(0);
int pos=-1;
int ma=-1;
for(int i=0;i<n;i++)
if(d[i]>ma)
{
ma=d[i];
pos=i;
}
//cout<<endl<<"pos="<<pos<<" max="<<ma<<endl;
//第二遍dfs
memset(vis,false,sizeof(vis));
memset(d,0,sizeof(d));
ma=-1;
vis[pos]=true;
dfs(pos);
for(int i=0;i<n;i++)
if(d[i]>ma)
{
ma=d[i];
pos=i;
}
//cout<<"pos="<<pos<<" max="<<ma<<endl;
int ans=ma*10+(ma+1)*ma/2;
printf("%d",ans);
return 0;
}
不得不说vector、栈、队列等数据结构真的好用,但是我这个菜鸡什么都不会。。以后抽空好好学吧555
2019年3月3日: 其实可以用前向星来做:
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<cstdlib>
using namespace std;
const int MAX=1e5+5;
int n;
struct Edge
{
int to,next,w;
}edge[MAX];
int head[MAX],tot;
void init()
{
tot=0;memset(head,-1,sizeof(head));
}
void addedge(int u,int v,int w)
{
edge[tot].to=v;edge[tot].w=w;edge[tot].next=head[u];head[u]=tot++;
}
bool vis[MAX];
int dis[MAX];
void dfs(int u,int pre)
{
for(int i=head[u];i!=-1;i=edge[i].next)
{
int v=edge[i].to;
if(v==pre)
continue;
int w=edge[i].w;
if(!vis[v])
{
vis[v]=true;
dis[v]=dis[u]+w;
dfs(v,u);
}
}
}
int main()
{
while(scanf("%d",&n)==1)
{
init();
int u,v,w;
for(int i=0;i<n-1;i++)
{
scanf("%d%d%d",&u,&v,&w);
addedge(u,v,w);
addedge(v,u,w);
}
int sta=1;
memset(vis,false,sizeof(vis));
memset(dis,0,sizeof(dis));
vis[sta]=true;
dis[sta]=0;
dfs(sta,0);
int ma=-1,pos=0;
for(int i=1;i<=n;i++)
if(dis[i]>ma)
{
ma=dis[i];
pos=i;
}
sta=pos,ma=0;
memset(vis,false,sizeof(vis));
memset(dis,0,sizeof(dis));
vis[sta]=true;
dis[sta]=0;
dfs(sta,0);
for(int i=1;i<=n;i++)
if(dis[i]>ma)
{
ma=dis[i];
pos=i;
}
int ans=10*ma+ma*(ma+1)/2;
printf("%d\n",ans);
}
return 0;
}