1. 程式人生 > >Beehives 找無向圖的最小環..BFS..

Beehives 找無向圖的最小環..BFS..

                 題意: 

                          給了一個無向圖(至多700個點,兩點間無重邊),問其中邊數最少的環是所少條邊

                 題解:

                          這類問題可以用Floyd做..但是會超時...

                          用BFS的方法,思路就是形成了環,則必然是搜尋樹上有了前向或者平行邊..列舉每個點位根..做BFS..按照遍歷的順序給每個點標號..當找到一個已經標號的邊..則知道形成了環..距離為dis[u]+dis[v]-1...但是這種方法只能求這種邊權值都為1的最小環...加些條件就很容易出錯了..而Floyd的方法適用範圍更廣...

Program(Floyd,TLE):

#include<iostream>
#include<stdio.h>
#include<string.h>
#include<queue>
#include<algorithm>
#include<cmath>
#define oo 1000000007
#define MAXN 505
using namespace std;
int Dist[MAXN][MAXN],Graph[MAXN][MAXN];

int MC(int nVertex)
{
      int mincircle=oo,i,j,k,temp;
      for (i=0;i<nVertex;i++)
        for (j=0;j<nVertex;j++)
           Dist[i][j]=Graph[i][j];
      for(k=0;k<nVertex;++k)
      {
          //新增部分:
           for(i=0;i<k;++i)
               for(j=0;j<i;++j)
                  if (mincircle>Dist[i][j]+Graph[j][k]+Graph[k][i])
                     mincircle = Dist[i][j]+Graph[j][k]+Graph[k][i];
         //通常的 floyd 部分:
           for(i=0;i<nVertex;++i)
              for(j=0;j<i;++j)
              {
                     temp = Dist[i][k] + Dist[k][j];
                     if(temp < Dist[i][j])
                        Dist[i][j] = Dist[j][i] = temp;
              }
      }
      return mincircle;
}

int main()
{
       int C,cases,N,M,u,v,ans; 
       scanf("%d",&C);
       for (cases=1;cases<=C;cases++)
       {
                scanf("%d%d",&N,&M);
                for (u=0;u<N;u++)
                   for (v=0;v<N;v++)
                      Graph[u][v]=oo;
                while (M--)
                {
                        scanf("%d%d",&u,&v);
                        Graph[u][v]=Graph[v][u]=1;
                }
                ans=MC(N);
                printf("Case %d: ",cases);
                if (ans==oo) puts("impossible");
                        else printf("%d\n",ans);
       }
       return 0;
}

Program(BFS,AC):
#include<iostream>
#include<stdio.h>
#include<string.h>
#include<queue>
#include<algorithm>
#include<cmath>
#define oo 1000000007
#define MAXN 505
using namespace std;
struct node
{
       int v,next,id;
}edge[50005];
int Ne,_next[MAXN],dfn[MAXN],id[MAXN],ans; 
queue<int> Q;
void addedge(int u,int v,int id)
{
       edge[++Ne].next=_next[u],_next[u]=Ne;
       edge[Ne].v=v,edge[Ne].id=id;
} 
int main()
{
       int C,cases,N,M,u,v,i,k;  
       scanf("%d",&C);
       for (cases=1;cases<=C;cases++)
       {
                scanf("%d%d",&N,&M);
                memset(_next,0,sizeof(_next)),Ne=0;
                for (i=1;i<=M;i++)
                {
                       scanf("%d%d",&u,&v),u++,v++;
                       addedge(u,v,i),addedge(v,u,i);
                }
                ans=oo;   
                for (i=1;i<=N;i++)
                {
                        memset(dfn,0x7f,sizeof(dfn));
                        memset(id,0,sizeof(id));        
                        Q.push(i);
                        dfn[i]=0;
                        while (Q.size())
                        {
                               u=Q.front(),Q.pop();
                               for (k=_next[u];k;k=edge[k].next)
                                   if (id[u]!=edge[k].id)
                                   {
                                           v=edge[k].v;
                                           if (dfn[v]>oo)
                                           {  
                                                 dfn[v]=dfn[u]+1;
                                                 id[v]=edge[k].id;
                                                 Q.push(v);
                                           }else
                                                 ans=min(ans,dfn[v]+dfn[u]+1);
                                   }
                        } 
                }
                printf("Case %d: ",cases);
                if (ans==oo) puts("impossible");
                        else printf("%d\n",ans);
       }
       return 0;
}