想看更多的解题报告: http://iyenn.com/rec/1824570.html
转载请注明出处:http://blog.csdn.net/wangjian8006
题目大意:给出n个点,在这些点中有些点是俱乐部点,并且有m个区域是由点围成的
输入第一行代表n个点
第二行代表m个区域
第3行代表俱乐部有L个
第四行有L个数,分别标记哪些个点事是俱乐部
接下来2*m行,代表m个区域,每个区域由两行表示,第一行为区域由T个点围成的,
第二行T个数代表是哪些点围成这个区域,这些点按逆时针围成这个区域,相邻两点代表一条边
最后一点和第一点也是一条边,这样就是一个闭合的区域
现在问,在图中找出一个区域,使得所有俱乐部点到这个区域所要穿过的边之和最少,
输出最少的边数之和
解题思路:先建图建错了,很尴尬的重新建图,将所有区域看成点建图,然后接下来的做法可以看代码注释
写完这题已经天黑了,被这题虐了一下午。...
- /*
- floyd
- Memory 788K
- Time 63MS
- */
- #include
- using namespace std;
- #define MAXE 205
- #define MAXV 255
- #define INF INT_MAX
- #define min(a,b) (a>b?b:a)
-
- int n,m;
- int club[35],clubsum; //俱乐部情况
- int regsum,firstv,secondv,tmpv,tmpedge; //用来处理区域
- int map[MAXE][MAXE]; //首先保存区域相邻情况,然后保存最短路径
- int edge[MAXV][MAXV]; //看边在哪个区域,一条边只能是包含两个区域
- int markedge[MAXV][MAXE]; //markedge[i][j]标记i点与j区域是否相邻
- int ans;
-
- void floyd(){
- int k,i,j;
- for(i=0;i
0; //这里注意初始化 -
- for(k=0;k
- for(i=0;i
- if(map[i][k]!=-1){
- for(j=0;j
- if(map[k][j]!=-1){
- //如果i到j走不通,直接赋值
- if(map[i][j]==-1 || map[i][k]+map[k][j]
- map[i][j]=map[i][k]+map[k][j];
- }
- }
- }
-
- int main(){
- #ifndef U
- freopen("d:\\test.in","r",stdin);
- #endif
- int i,j,k;
- int tmpv,tmpedge;
- while(~scanf("%d",&m)){
- scanf("%d%d",&n,&clubsum);
- for(i=0;i
scanf("%d",&club[i]); -
- memset(map,-1,sizeof(map));
- memset(markedge,0,sizeof(markedge));
- memset(edge,-1,sizeof(edge));
- for(i=0;i
- scanf("%d%d",®sum,&firstv);
- tmpv=firstv;
- markedge[firstv][i]=1;
- for(j=1;j
- scanf("%d",&secondv);
- markedge[secondv][i]=1; //标记点和区域相邻
- tmpedge=edge[tmpv][secondv];
- if(tmpedge!=-1){ //一条边只被两个区域包含
- map[tmpedge][i]=map[i][tmpedge]=1; //这两个区域相邻了
- }else{
- edge[tmpv][secondv]=edge[secondv][tmpv]=i;
- }
-
- tmpv=secondv;
- }
- tmpedge=edge[tmpv][firstv];
- if(tmpedge!=-1){
- map[tmpedge][i]=map[i][tmpedge]=1;
- }else{
- edge[tmpv][firstv]=edge[firstv][tmpv]=i;
- }
- }
- //得到相邻区域的图后求最短路径
- floyd();
-
- ans=INF;
- for(i=0;i
- int sum=0;
- for(j=0;j
//找出和俱乐部点相邻的区域,在这些区域到i区域的一个最小值之和与答案比较 - tmpv=INF;
- for(k=0;k
- if(markedge[club[j]][k]){
- tmpv=min(tmpv,map[k][i]);
- }
- sum+=tmpv;
- }
- ans=min(ans,sum);
- }
- printf("%d\n",ans);
- }
- return 0;
- }
=================================================================
- /*
- 前面错误的代码留着做个纪念吧
- */
- #include
- #include
- using namespace std;
- #define MAXV 260
- #define MAXR 210
- #define INF INT_MAX
- #define min(a,b) (a>b?b:a)
-
- int map[MAXV][MAXV]; //存边的连通情况
- int ans[MAXV][MAXR]; //存点到地区最少要穿过几条线
- int m,n; //地区与点的总数
- int club[40],clubsum; //俱乐部的情况
- int vsum[MAXR],ver[MAXR][MAXV]; //存地区情况
- int flag[MAXR]; //存边界情况,flag标记地区是否为边界地区
- int d[MAXV][MAXV]; //从点到其他点最少经过几条边
-
- void bfs(int first){
- queue <int>q;
- bool vis[MAXV];
- int i,v;
- memset(vis,0,sizeof(vis));
-
- q.push(first);
- vis[first]=1;
- while(!q.empty()){
- v=q.front();q.pop();
- for(i=1;i<=n;i++)
- if(!vis[i] && map[v][i]){
- q.push(i);
- vis[i]=1;
- d[first][i]=d[first][v]+1;
- }
- }
- }
-
- int main(){
- #ifndef U
- // freopen("d:\\test.in","r",stdin);
- #endif
- int i,j,k;
- int key,tmp,vtmp;
- while(~scanf("%d",&m)){
- scanf("%d%d",&n,&clubsum);
- for(i=0;i
scanf("%d",&club[i]); //输入俱乐部情况 -
- tmp=-1;
- memset(map,0,sizeof(map)); //输入地区情况,并且连边
- for(i=0;i
- scanf("%d%d",&vsum[i],&ver[i][0]);
- for(j=1;j
- scanf("%d",&ver[i][j]);
- map[ver[i][j-1]][ver[i][j]]=map[ver[i][j]][ver[i][j-1]]=1;
- }
- map[ver[i][j-1]][ver[i][0]]=map[ver[i][0]][ver[i][j-1]]=1;
- if(vsum[i]>tmp){tmp=vsum[i];vtmp=i;}
- }
-
- memset(flag,0,sizeof(flag));
- for(i=0;i
- for(j=0;j
- if(!flag[j]){
- for(k=0;k
- if(ver[vtmp][i]==ver[j][k]) break;
- }
- if(k
1; - }
- }
-
- memset(d,0,sizeof(d));
- for(i=1;i<=n;i++) bfs(i);
-
- for(i=1;i<=n;i++){
- for(j=0;j
- ans[i][j]=d[i][ver[j][0]];
- for(k=1;k
- ans[i][j]=min(ans[i][j],d[i][ver[j][k]]);
- }
- }
- }
-
- for(i=0;i
- for(j=0;j
- if(flag[j])
- ans[ver[vtmp][i]][j]=min(ans[ver[vtmp][i]][j],1);
- }
-
- key=INF;
- for(i=0;i
- tmp=0;
- for(j=0;j
- tmp+=ans[club[j]][i];
- }
- key=min(key,tmp);
- }
- printf("%d\n",key);
- }
- return 0;
- }
注:本文转载自blog.csdn.net的wangjian8006的文章"http://blog.csdn.net/wangjian8006/article/details/7958838"。版权归原作者所有,此博客不拥有其著作权,亦不承担相应法律责任。如有侵权,请联系我们删除。
评论记录:
回复评论: