symons

___________每一天都是幸福的!!

  博客园  ::  :: 新随笔  ::  :: 订阅 订阅  :: 管理

  这题卡了我好几天,我太菜了。周四卡了一下午,周五没怎么看这个,然后晚上+周⑥一天+周日上午我都去踢球了,吼吼。然后我今天我给过了,哈哈

  开始使用的是找点,建边,用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的代码,够长,写的略微繁琐一点了,大家将就看吧。

posted on 2012-10-28 13:56  symons  阅读(433)  评论(0编辑  收藏  举报