hdu 4514—— 湫湫系列故事——设计风景线

来源:互联网 发布:米折是淘宝网的吗 编辑:程序博客网 时间:2024/05/20 05:28

tarjan+bfs搜索


#include<iostream>#include<cstdio>#include<cstdio>#include<queue>#pragma comment(linker, "/STACK:1024000000,1024000000")   //扩栈 using namespace std;#define maxn 110000#define maxm 2100000int n,m;int head[maxn],v[maxm],next[maxm],w[maxm],cnt;int dfn[maxn],low[maxn],step;int sta[maxn],top;int ID[maxn],IdNum;int vis[maxn];int r;void Init() {memset(vis,0,sizeof(vis));memset(head,-1,sizeof(head));memset(dfn,0,sizeof(dfn));memset(low,0,sizeof(low));IdNum=top=step=cnt=0;}void add(int a,int b,int c){v[cnt]=b;next[cnt]=head[a];w[cnt]=c;head[a]=cnt++;}void tarjan(int u,int pre) //pre为前一个点 {dfn[u]=low[u]=++step;sta[++top]=u;vis[u]=1;int k=0;for(int i=head[u];~i;i=next[i]){int to=v[i];if(!dfn[to])//如果没有进过栈 {tarjan(to,u);//继续找 low[u]=min(low[u],low[to]);}else{if(to==pre)//如果是前一个点 {if(k)//考虑了重边的可能 low[u]=min(low[u],dfn[to]);k++;//无向边是建2条边 }else if(vis[to])low[u]=min(low[u],dfn[to]);}}if(dfn[u]==low[u]){IdNum++;int x;do{x=sta[top--];vis[x]=0;ID[x]=IdNum;//表示在同一个强连通分量 }while(u!=x);}}int dis[maxn];  int bfs(int x)  {      queue<int> q;          memset(dis,-1,sizeof(dis));      q.push(x);      dis[x]=0;    int k;    while(!q.empty())      {          int u=q.front();          q.pop();        if(dis[u]>r)        {        k=u;        r=dis[u];        }        for(int i=head[u];~i;i=next[i])          {              int to=v[i];              if(dis[to]==-1)              {                  dis[to]=dis[u]+w[i];                  q.push(to);            }          }      } //cout<<k<<endl;    return k; }  int main(){int x,y,z;while(~scanf("%d%d",&n,&m)){Init();for(int i=1;i<=m;i++){scanf("%d%d%d",&x,&y,&z);add(x,y,z);add(y,x,z);}for(int i=1;i<=n;i++)if(!dfn[i])tarjan(1,-1); //cout<<IdNum<<endl;if(IdNum<n){cout<<"YES"<<endl;continue;}r=-1;memset(dis,-1,sizeof(dis));for(int i=1;i<=n;i++)if(dis[i]==-1)bfs(bfs(i));//2次bfs找树的直径   printf("%d\n",r);}return 0;}