Beehives 找無向圖的最小環..BFS..
阿新 • • 發佈:2019-02-01
題意:
給了一個無向圖(至多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; }