这题卡了我好几天,我太菜了。周四卡了一下午,周五没怎么看这个,然后晚上+周⑥一天+周日上午我都去踢球了,吼吼。然后我今天我给过了,哈哈
开始使用的是找点,建边,用kruskal,然后果断超时,以为是思路问题,可能会prim好一点吧,但是我坚持没看题解。到底哪会超时呢,后来已经决定用prim写了,后来黄老师说用kruskal就行,就是确定两点之间距离时候用BFS时候我的时间复杂度不对。应该是遍历一遍所有的点,是从一个点找到所有的点,我的方法是双重循环,每两个点之间搜一次,黄老师说这样太慢了,后来我经过启发改了,可是还是错。
最后我发现出bug了,原因是把i,j定义为全局变量了,坑爹啊。
这题现在看是没什么,就是找到所有的A,S点,然后建边,然后用kruskal算法直接一算就可以了。
1 #include <iostream> 2 #include <cstring> 3 #include <queue> 4 #include <algorithm> 5 #define maxn 100+5 6 #define maxm 100000+100 7 using namespace std; 8 string gird[55]; 9 int P[100+10][100+10];//建图 10 bool GIRD[55][55];//用于宽搜 11 int dir[4][2]={0,1,0,-1,1,0,-1,0}; 12 int parent[maxn]; 13 int I,J; 14 int u,v; 15 int n,m; 16 struct edge 17 { 18 int u,v,w; 19 }edges[maxm]; 20 struct point 21 { 22 int x,y,steps,num; 23 }points[maxn]; 24 void ufset() 25 { 26 memset(parent,-1,sizeof(parent)); 27 } 28 int find(int x) 29 { 30 int s; 31 for(s=x;parent[s]>=0;s=parent[s]) ; 32 while(s!=x) 33 { 34 int tmp=parent[x]; 35 parent[x]=s; 36 x=tmp; 37 } 38 return s; 39 } 40 void Union(int R1,int R2) 41 { 42 int r1=find(R1),r2=find(R2); 43 int tmp=parent[r1]+parent[r2]; 44 if(parent[r1]>parent[r2]) 45 { 46 parent[r1]=r2; 47 parent[r2]=tmp; 48 } 49 else 50 { 51 parent[r2]=r1; 52 parent[r1]=tmp; 53 } 54 } 55 int kruskal() 56 { 57 int i,j; 58 int num=0; 59 int sumweight=0; 60 ufset(); 61 for(i=0;i<m;++i) 62 { 63 u=edges[i].u; v=edges[i].v; 64 if(find(u)!=find(v)) 65 { 66 sumweight+=edges[i].w; num++; 67 Union(u,v); 68 } 69 } 70 return sumweight; 71 } 72 bool cmp(edge aa,edge bb) 73 { 74 return aa.w<bb.w; 75 } 76 int findnumber(int xx,int yy) 77 { 78 int i,j; 79 for(i=0;i<n;++i) 80 { 81 if(points[i].x==xx&&points[i].y==yy) 82 return points[i].num; 83 } 84 } 85 void bfs(int bx,int by,int bn) 86 { 87 int i,j; 88 int number; 89 point p,p1,p2,p3; 90 queue<point>haha; 91 memset(GIRD,0,sizeof(GIRD)); 92 p.x=bx;p.y=by;p.steps=0; 93 haha.push(p); 94 GIRD[bx][by]=1; 95 while(haha.size()>0) 96 { 97 p1=haha.front(); 98 haha.pop(); 99 for(i=0;i<4;++i) 100 { 101 p2.x=p1.x+dir[i][0]; 102 p2.y=p1.y+dir[i][1]; 103 p2.steps=p1.steps+1; 104 if(p2.x>=0&&p2.x<I&&p2.y>=0&&p2.y<J&&GIRD[p2.x][p2.y]==0) 105 { 106 GIRD[p2.x][p2.y]=1; 107 if(gird[p2.x][p2.y]!='#') 108 { 109 haha.push(p2); 110 if(gird[p2.x][p2.y]=='A'||gird[p2.x][p2.y]=='S') 111 { 112 number=findnumber(p2.x,p2.y); 113 P[bn][number]=p2.steps; 114 P[number][bn]=p2.steps; 115 } 116 } 117 } 118 } 119 } 120 return; 121 } 122 int main() 123 { 124 int t; 125 int i,j; 126 cin>>t; 127 while(t--) 128 { 129 memset(P,0,sizeof(P)); 130 n=0; 131 m=0; 132 cin>>J>>I; 133 getline(cin,gird[0]); 134 for(i=0;i<I;++i) 135 { 136 getline(cin,gird[i]); 137 for(j=0;j<J;++j) 138 { 139 if(gird[i][j]=='A'||gird[i][j]=='S') 140 { 141 points[n].x=i; 142 points[n].y=j; 143 points[n].num=n; 144 n++; 145 } 146 } 147 } 148 for(i=0;i<n;++i) 149 { 150 bfs(points[i].x,points[i].y,points[i].num); 151 } 152 for(i=0;i<n;++i) 153 { 154 for(j=0;j<i;++j) 155 { 156 edges[m].u=points[i].num; 157 edges[m].v=points[j].num; 158 edges[m].w=P[points[i].num][points[j].num]; 159 m++; 160 } 161 } 162 sort(edges,edges+m,cmp); 163 cout<<kruskal()<<endl; 164 } 165 }
3K的代码,够长,写的略微繁琐一点了,大家将就看吧。