最小生成树练习3(普里姆算法Prim)
poj1258 Agri-Net(最小生成树)水题。
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 using namespace std; 5 const int inf=0x3f3f3f3f; 6 const int N=101; 7 int n,m; 8 int g[N][N],low[N]; 9 void prim(int u0){ 10 int i,j,mi,v,ans=0; 11 for(i=0;i<n;++i){ 12 low[i]=g[u0][i]; 13 } 14 low[u0]=-1; 15 for(i=1;i<n;++i){ 16 mi=inf; 17 v=-1; 18 for(j=0;j<n;++j) 19 if(low[j]!=-1&&low[j]<mi){ 20 v=j; mi=low[j]; 21 } 22 ans+=low[v]; 23 low[v]=-1; 24 for(j=0;j<n;++j){ 25 if(g[v][j]<low[j]){ 26 low[j]=g[v][j]; 27 } 28 } 29 } 30 printf("%d\n",ans); 31 } 32 int main(){ 33 int t,i,j; 34 while(scanf("%d",&n)==1){ 35 memset(g,inf,sizeof(inf)); 36 for(i=0;i<n;++i) 37 for(j=0;j<n;++j) 38 scanf("%d",&g[i][j]); 39 prim(0); 40 } 41 return 0; 42 }
poj1751 Highways(最小生成树)水题。已修好的路赋值为0。不用sqrt计算距离,因为题目没要求。做完这题后把自学时的模板改了一点,因为一开始的模板太挫。。
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 #include<cmath> 5 using namespace std; 6 const int inf=0x3f3f3f3f; 7 const int N=751; 8 int n,m; 9 int g[N][N],low[N],near[N],x[N],y[N]; 10 void prim(int u0){ 11 int i,j,mi,v; 12 for(i=1;i<=n;++i){ 13 low[i]=g[u0][i]; 14 near[i]=u0; 15 } 16 low[u0]=-1; 17 for(i=1;i<n;++i){ 18 mi=inf; 19 v=-1; 20 for(j=1;j<=n;++j) 21 if(low[j]!=-1&&low[j]<mi){ 22 v=j; mi=low[j]; 23 } 24 if(mi!=0)printf("%d %d\n",near[v],v); 25 low[v]=-1; 26 for(j=1;j<=n;++j){ 27 if(g[v][j]<low[j]){ 28 low[j]=g[v][j]; 29 near[j]=v; 30 } 31 } 32 } 33 } 34 int main(){ 35 int t,i,j; 36 scanf("%d",&n); 37 memset(g,inf,sizeof(g)); 38 for(i=1;i<=n;++i) scanf("%d%d",&x[i],&y[i]); 39 for(i=1;i<=n;++i){ 40 for(j=i+1;j<=n;++j){ 41 g[i][j]=g[j][i]=(x[i]-x[j])*(x[i]-x[j])+(y[i]-y[j])*(y[i]-y[j]); 42 } 43 } 44 scanf("%d",&m); 45 while(m--){ 46 scanf("%d%d",&i,&j); 47 g[i][j]=g[j][i]=0; 48 } 49 prim(1); 50 return 0; 51 }
poj1789 Truck History(最小生成树)每种卡车类型都是由其他卡车类型派生出来,第一种除外。理解:顶点为卡车类型,边的权值为类型对(t0,d0)的距离(编码中不同字符的位置数目)。。看懂题看得头疼,其实不难做。
1 #include<cstdio> 2 #include<cstring> 3 using namespace std; 4 const int inf=0x3f3f3f3f; 5 const int N=2001; 6 int n; 7 char code[N][8]; 8 int g[N][N],low[N],a[N],ans; 9 void prim(int u0){ 10 int i,j,mi,v; 11 ans=0; 12 for(i=0;i<n;++i){ 13 low[i]=g[u0][i]; 14 } 15 low[u0]=-1; 16 for(i=1;i<n;++i){ 17 mi=inf; 18 v=-1; 19 for(j=0;j<n;++j) 20 if(low[j]!=-1&&low[j]<mi){ 21 v=j; mi=low[j]; 22 } 23 ans+=low[v]; 24 low[v]=-1; 25 for(j=0;j<n;++j){ 26 if(g[v][j]<low[j]) 27 low[j]=g[v][j]; 28 } 29 } 30 printf("The highest possible quality is 1/%d.\n",ans); 31 } 32 int main(){ 33 int i,j,k,d; 34 while(scanf("%d",&n),n){ 35 memset(g,inf,sizeof(g)); 36 for(i=0;i<n;++i) scanf("%s",code[i]); 37 for(i=0;i<n-1;++i){ 38 for(j=i+1;j<n;++j){ 39 d=0; 40 for(k=0;k<7;++k) 41 d+=(code[i][k]!=code[j][k]); 42 g[i][j]=g[j][i]=d; 43 } 44 } 45 prim(0); 46 } 47 return 0; 48 }
poj2349 Arctic Network(最小生成树)求出最小生成树,将边从大到小排序,前s-1条用s个卫星通信,第s大边即为答案。
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 #include<cmath> 5 using namespace std; 6 const int inf=0x3f3f3f3f; 7 const int N=501; 8 int n,s; 9 double g[N][N],low[N],d[N],x[N],y[N]; 10 int cmp(int a,int b){ 11 return a > b; 12 } 13 void prim(int u0){ 14 int i,j,mi,v; 15 int cnt=0; 16 for(i=0;i<n;++i){ 17 low[i]=g[u0][i]; 18 } 19 low[u0]=-1; 20 for(i=1;i<n;++i){ 21 mi=inf; 22 v=-1; 23 for(j=0;j<n;++j) 24 if(low[j]!=-1&&low[j]<mi){ 25 v=j; mi=low[j]; 26 } 27 d[cnt++]=low[v]; 28 low[v]=-1; 29 for(j=0;j<n;++j){ 30 if(g[v][j]<low[j]) 31 low[j]=g[v][j]; 32 } 33 } 34 sort(d,d+cnt,cmp); 35 printf("%.2f\n",d[s-1]); 36 } 37 int main(){ 38 int t,i,j; 39 double d; 40 scanf("%d",&t); 41 while(t--){ 42 memset(g,inf,sizeof(g)); 43 scanf("%d%d",&s,&n); 44 for(i=0;i<n;++i) scanf("%lf%lf",&x[i],&y[i]); 45 for(i=0;i<n;++i){ 46 for(j=i+1;j<n;++j){ 47 d=sqrt((x[i]-x[j])*(x[i]-x[j])+(y[i]-y[j])*(y[i]-y[j])); 48 g[i][j]=g[j][i]=d; 49 } 50 } 51 prim(0); 52 } 53 return 0; 54 }
poj3026 Borg Maze(最小生成树,bfs预处理)因为这题我几天没打码了,今天做出来感觉也不是很难。还是深感基础之弱内心痛苦。。对了,记得看discuss哦,如果你不想多挥霍青春的话。。。
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 #include<queue> 5 using namespace std; 6 const int inf=0x3f3f3f3f; 7 const int N=51; 8 const int M=102; 9 int x,y; 10 int n; 11 int dir[][2]={0,1,0,-1,1,0,-1,0}; 12 int g[M][M],low[M]; 13 char mp[N][N]; 14 int G[N][N]; 15 int vd[N][N]; 16 void bfs(int sx,int sy){ 17 queue<pair<int,int> >q; 18 while(!q.empty())q.pop(); 19 memset(vd,-1,sizeof(vd)); 20 vd[sx][sy]=0; 21 q.push(make_pair(sx,sy)); 22 while(!q.empty()){ 23 pair<int,int>u=q.front(); q.pop(); 24 if(G[u.first][u.second]>0) 25 g[G[sx][sy]][G[u.first][u.second]]=vd[u.first][u.second]; 26 for(int i=0;i<4;++i){ 27 int xx=u.first+dir[i][0]; 28 int yy=u.second+dir[i][1]; 29 if(mp[xx][yy]=='#'||vd[xx][yy]!=-1)continue; 30 vd[xx][yy]=vd[u.first][u.second]+1; 31 q.push(make_pair(xx,yy)); 32 } 33 } 34 } 35 void prim(int u0){ 36 int i,j,mi,v,ans=0; 37 for(i=1;i<n;++i) low[i]=g[u0][i]; 38 low[u0]=-1; 39 for(i=1;i<n-1;++i){ 40 mi=inf; 41 v=-1; 42 for(j=1;j<n;++j) 43 if(low[j]!=-1&&low[j]<mi){ 44 v=j; mi=low[j]; 45 } 46 ans+=low[v]; 47 low[v]=-1; 48 for(j=1;j<n;++j){ 49 if(g[v][j]<low[j]){ 50 low[j]=g[v][j]; 51 } 52 } 53 } 54 printf("%d\n",ans); 55 } 56 int main(){ 57 int t,i,j; 58 scanf("%d",&t); 59 while(t--){ 60 scanf("%d%d",&x,&y); 61 gets(mp[0]); 62 for(i=0;i<y;++i) gets(mp[i]); 63 n=1; 64 for(i=0;i<y;++i){ 65 for(j=0;j<x;++j){ 66 if(mp[i][j]=='A'||mp[i][j]=='S') 67 G[i][j]=n++; 68 else G[i][j]=-1; 69 } 70 } 71 for(i=0;i<y;++i) 72 for(j=0;j<x;++j) 73 if(G[i][j]>0) bfs(i,j); 74 prim(1); 75 } 76 return 0; 77 }