LGP4289

大概说一下思路

**1.贪心**

两个图都为1时这一点按兵不动,这里蒟蒻开始认为这个贪心有问题,例如这个数据.

初: 
 
    1 0 1 1
    1 1 1 1
    0 1 0 0
    0 0 0 0
 
末: 

    1 1 1 1
    1 1 1 1
    0 0 0 0
    0 0 0 0
    
这样看初状态(3,2)的1按照上面的贪心似乎走不了,只能(2,2)的1走动,(3,2)的

1再走.其实我们可以认为(3,2)的1可以走在(2,2)的上面再走.这就与上面"按兵

不动的贪心不违背.

**2.d j**

将初位置不重复的点放入q1,末位置不重复的点放入q2

再用~~迪杰斯特拉~~跑网状图得到q1,q2两两对应最短路径的矩阵.

**3.d f s**

在2得到的矩阵上dfs行与列在唯一两两对应的上的最小值.
code:

  1 #include<iostream>
  2 #include<cstdlib>
  3 #include<cstdio>
  4 #include<queue>
  5 using namespace std;
  6 #define R register
  7 long long ans=1e9+1;
  8 int len1,len2,len3,tap,cnt,head[110],dis[110],w[20],check[110],fmap[10][10],emap[10][10],val[20][20],vis[10][10],id[10][10],dx[5]={0,-1,1,0,0},dy[5]={0,0,0,-1,1};
  9 struct dl1{
 10     int x,y;
 11 }q1[110];
 12 struct dl2{
 13     int x,y;
 14 }q2[110];
 15 struct bian{
 16     int to,next,v;
 17 }len[110];
 18 void add(int from,int to,int v)
 19 {
 20     len[++cnt].v=v;
 21     len[cnt].to=to;
 22     len[cnt].next=head[from];
 23     head[from]=cnt;
 24 }
 25 void dj(int s)
 26 {
 27     for(R int k=1;k<=16;++k)
 28         dis[k]=19260817,check[k]=0;
 29     priority_queue<pair<int,int> >q;
 30     q.push(make_pair(0,s));
 31     dis[s]=0;
 32     while(q.size())
 33     {
 34         int now=q.top().second;
 35         q.pop();
 36         if(check[now]) continue;
 37         check[now]=1;
 38         for(R int k=head[now];k;k=len[k].next)
 39         {
 40             int to=len[k].to,v=len[k].v;
 41             if(dis[to]>dis[now]+v)
 42             {
 43                 dis[to]=dis[now]+v;
 44                 q.push(make_pair(-dis[to],to));
 45             }
 46         }
 47     }
 48 }
 49 void dfs(int x,long long step)
 50 {
 51     if(x==len1+1)
 52     {
 53         ans=min(ans,step);
 54         return;
 55     }
 56     for(R int k=1;k<=len1;++k)
 57         if(!w[k])
 58         {
 59             w[k]=1;
 60             long long nowstep=step+val[x][k];
 61             dfs(x+1,nowstep);
 62             w[k]=0;
 63         }
 64 }
 65 int main()
 66 {    
 67     //freopen("New.in","r",stdin);
 68     //freopen("New.out","w",stdout);
 69     for(R int i=1;i<=4;++i)
 70         for(R int j=1;j<=4;++j)
 71         {
 72             scanf("%1d",&fmap[i][j]);
 73             id[i][j]=++tap;
 74         }
 75     for(R int i=1;i<=4;++i)
 76         for(R int j=1;j<=4;++j)
 77         {
 78             scanf("%1d",&emap[i][j]);
 79             if(emap[i][j]==fmap[i][j])
 80                 emap[i][j]=fmap[i][j]=0;
 81         }
 82     for(R int i=1;i<=4;++i)
 83         for(R int j=1;j<=4;++j)
 84             if(fmap[i][j])
 85                 q1[++len1].x=i,q1[len1].y=j;
 86     for(R int i=1;i<=4;++i)
 87         for(R int j=1;j<=4;++j)
 88             if(emap[i][j])
 89                 q2[++len2].x=i,q2[len2].y=j;
 90     for(R int i=1;i<=4;++i)
 91         for(R int j=1;j<=4;++j)    
 92         {
 93             int x=i,y=j;
 94             for(R int k=1;k<=4;++k)
 95             {
 96                 int nowx=x+dx[k],nowy=y+dy[k];
 97                 if(nowx>=1&&nowx<=4&&nowy>=1&&nowy<=4)
 98                 {
 99                     int id1=id[x][y],id2=id[nowx][nowy];
100                     add(id1,id2,1);
101                 }    
102             }
103         }
104     for(R int i=1;i<=len1;++i)
105     {
106         int id1=id[q1[i].x][q1[i].y];
107         dj(id1);
108         for(R int j=1;j<=len2;++j)
109         {
110             int id2=id[q2[j].x][q2[j].y];
111             val[i][j]=dis[id2];
112         }
113     }
114     dfs(1,0);
115     printf("%lld",ans);
116     return 0;
原文地址:https://www.cnblogs.com/xqysckt/p/11194920.html