zoukankan      html  css  js  c++  java
  • CF1065D Three Pieces (多元最短路)

    题目大意:给你一个棋盘,你需要控制棋子依次经过编号为1~n的所有点,棋子的可以是车,马,象,都依照国际象棋的行棋方式,每走一步消耗1单位时间,但每次更换棋子都需要额外1单位时间,求经过所有点需要的最少时间 ,如果多种方案需要的最少时间相同,输出更换棋子次数最少的那个

    有的机房老人用了记忆化搜索,但写起来好像很蛋疼。神仙学弟phy想了一个多元最短路,简洁好写

    每个点有三种状态,先暴力建边。

    然后根据点的编号从小到大,以每个点为源点跑一次两元最短路

    注意,不能在个点都记录超级源点/汇点,因为这样做会让更换棋子的步骤失效!

    所以,每当跑完某个点的最短路时,先记录当前下一个点的三种状态的花费,从下一个编号的点开始跑时,先清数组,再把上次记录的花费扔到起始状态里,再去跑这个点为源点的最短路
    接下来就是多元最短路了,可以用重载运算符,比较好写

      1 #include <queue>
      2 #include <cstdio>
      3 #include <cstring>
      4 #include <algorithm>
      5 #define N 15
      6 #define M 500
      7 #define inf 66666666
      8 using namespace std;
      9 
     10 int n,cte,num;
     11 int mp[N][N],id[N][N][4],head[M];
     12 int px[M],py[M];
     13 struct node{int d,w;
     14     friend bool operator < (const node &s1,const node &s2){
     15         if(s1.d!=s2.d) return s1.d<s2.d;
     16         else return s1.w<s2.w;
     17     }node(int d,int w):d(d),w(w){} node(){}
     18 };
     19 struct Edge{int to,nxt,d,w;}edge[M*50];
     20 void ae(int u,int v,int d,int w){
     21     cte++;edge[cte].to=v,edge[cte].nxt=head[u];
     22     edge[cte].d=d,edge[cte].w=w,head[u]=cte;
     23 }
     24 inline int check(int x,int y)
     25 {return 1<=x&&x<=n&&1<=y&&y<=n;}
     26 void Build_Edge()
     27 {
     28     int s0,s1,s2,s3,t1,t2,t3;
     29     for(int i=1;i<=n;i++)
     30         for(int j=1;j<=n;j++){
     31             s1=id[i][j][1],s2=id[i][j][2],s3=id[i][j][3];
     32             ae(s1,s2,1,1),ae(s2,s1,1,1),ae(s1,s3,1,1),ae(s3,s1,1,1),ae(s2,s3,1,1),ae(s3,s2,1,1);
     33             for(int x=1;x<=n;x++){if(!check(i+x,j))break;t1=id[i+x][j][1],ae(s1,t1,1,0);}
     34             for(int x=1;x<=n;x++){if(!check(i,j+x))break;t1=id[i][j+x][1],ae(s1,t1,1,0);}
     35             for(int x=1;x<=n;x++){if(!check(i-x,j))break;t1=id[i-x][j][1],ae(s1,t1,1,0);}
     36             for(int x=1;x<=n;x++){if(!check(i,j-x))break;t1=id[i][j-x][1],ae(s1,t1,1,0);}
     37             
     38             for(int x=1;x<=n;x++){if(!check(i+x,j+x))break;t3=id[i+x][j+x][3],ae(s3,t3,1,0);}
     39             for(int x=1;x<=n;x++){if(!check(i-x,j+x))break;t3=id[i-x][j+x][3],ae(s3,t3,1,0);}
     40             for(int x=1;x<=n;x++){if(!check(i+x,j-x))break;t3=id[i+x][j-x][3],ae(s3,t3,1,0);}
     41             for(int x=1;x<=n;x++){if(!check(i-x,j-x))break;t3=id[i-x][j-x][3],ae(s3,t3,1,0);}
     42             
     43             if(check(i+1,j+2))t2=id[i+1][j+2][2],ae(s2,t2,1,0);
     44             if(check(i+2,j+1))t2=id[i+2][j+1][2],ae(s2,t2,1,0);
     45             if(check(i-1,j-2))t2=id[i-1][j-2][2],ae(s2,t2,1,0);
     46             if(check(i-2,j-1))t2=id[i-2][j-1][2],ae(s2,t2,1,0);
     47             if(check(i+1,j-2))t2=id[i+1][j-2][2],ae(s2,t2,1,0);
     48             if(check(i+2,j-1))t2=id[i+2][j-1][2],ae(s2,t2,1,0);
     49             if(check(i-1,j+2))t2=id[i-1][j+2][2],ae(s2,t2,1,0);
     50             if(check(i-2,j+1))t2=id[i-2][j+1][2],ae(s2,t2,1,0);
     51         }
     52 
     53 }
     54 node dis[M],lst[5];int use[M];
     55 node SPFA()
     56 {
     57     int s1,s2,s3,t1,t2,t3;
     58     queue<int>q;node tmp;
     59     for(int i=1;i<n*n;i++)
     60     {
     61         memset(dis,0x3f,sizeof(dis));
     62         memset(use,0,sizeof(use));
     63         s1=id[px[i]][py[i]][1];
     64         s2=id[px[i]][py[i]][2];
     65         s3=id[px[i]][py[i]][3];
     66         dis[s1]=lst[1],dis[s2]=lst[2],dis[s3]=lst[3];
     67         use[s1]=1,use[s2]=1,use[s3]=1;
     68         q.push(s1),q.push(s2),q.push(s3);
     69         while(!q.empty())
     70         {
     71             int x=q.front();q.pop();
     72             tmp=dis[x];
     73             for(int j=head[x];j;j=edge[j].nxt){
     74                 int v=edge[j].to;
     75                 tmp.d+=edge[j].d,tmp.w+=edge[j].w;
     76                 if(tmp<dis[v]){ dis[v]=tmp;
     77                     if(!use[v]) use[v]=1,q.push(v);
     78                 }tmp=dis[x];
     79             }use[x]=0;
     80         }
     81         t1=id[px[i+1]][py[i+1]][1];
     82         t2=id[px[i+1]][py[i+1]][2];
     83         t3=id[px[i+1]][py[i+1]][3];
     84         lst[1]=dis[t1],lst[2]=dis[t2],lst[3]=dis[t3];
     85     }
     86     node ret;ret.d=inf,ret.w=inf;
     87     s1=id[px[n*n]][py[n*n]][1];
     88     s2=id[px[n*n]][py[n*n]][2];
     89     s3=id[px[n*n]][py[n*n]][3];
     90     if(dis[s1]<ret) ret=dis[s1];
     91     if(dis[s2]<ret) ret=dis[s2];
     92     if(dis[s3]<ret) ret=dis[s3];
     93     return ret;
     94 }
     95 
     96 int main()
     97 {
     98     //freopen("t1.in","r",stdin);
     99     scanf("%d",&n);
    100     for(int i=1;i<=n;i++)
    101         for(int j=1;j<=n;j++)
    102             scanf("%d",&mp[i][j]),id[i][j][1]=++num,id[i][j][2]=++num,
    103             id[i][j][3]=++num,px[mp[i][j]]=i,py[mp[i][j]]=j;
    104     Build_Edge();
    105     node ret=SPFA();
    106     printf("%d %d
    ",ret.d,ret.w);
    107     return 0;
    108 }
  • 相关阅读:
    分享我的2014年3月unity3d面试题与参考答案(转)
    Unity3D 面试ABC
    MiniJson解释Json字符串
    Unity3D研究之支持中文与本地文件的读取写入(转)
    unity3d--NGUI制作中文字体
    吊炸天之十步完全理解SQL
    mysql主从同步碰到的问题
    Redis 安装碰到问题
    在Centos系统下使用命令安装gnome图形界面程序
    centos7 网络问题
  • 原文地址:https://www.cnblogs.com/guapisolo/p/9894352.html
Copyright © 2011-2022 走看看