题目链接
题目描述:
思路分析:
DP[i][j]表示将初始位置为K的电脑进行第i次操作后当前位置为j的最小不执行命令次数。
这题的DP方程是真的巧妙,因为我们考虑的是初始位置为K的电脑最终放在j位置的最小不执行次数,所以每一个交换命令意味着,1、这一层交换不执行,坏电脑在X位置的最小并不执行次数就是就在上一层状态x不执行次数加一,2、执行就是坏电脑在Y的位置移到了X位置,所以坏电脑在X位置的最小不执行次数就等于上一层坏电脑在Y位置的最小不移动次数(第一次见这样的状态转移方式记录一下)。因为每一层只交换命令的x,y,其他位置不变所以时间复杂度为O(m).
题目代码:
#include<bits/stdc++.h>
using namespace std;
const int INF=0x3f3f3f3f;
int t;
int n,m,k;
struct ty{
int x;
int y;
};
ty a[100005];
int f[2][100005];
int main(){
scanf(" %d",&t);
while(t--){
scanf(" %d %d %d",&n,&m,&k);
for(int i=1;i<=m;i++) scanf(" %d %d",&a[i].x,&a[i].y);
for(int i=0;i<=1;i++){
for(int j=0;j<=100001;j++) f[i][j]=INF;
}
f[0][k]=0;
f[1][k]=0;
for(int i=1;i<=m;i++){
//for(int j=1;j<=n;j++) f[i&1][j]=f[(i-1)&1][j];
int x=a[i].x,y=a[i].y;
/*1、这一层交换不执行,坏电脑在X位置的最小并不执行次数就是就在上一层状态x不执行次数加一
2、执行就是坏电脑在Y的位置移到了X位置,
所以坏电脑在X位置的最小不执行次数就等于上一层坏电脑在Y位置的最小不移动次数 */
f[i&1][x]=min(f[(i-1)&1][y],f[(i-1)&1][x]+1);
f[i&1][y]=min(f[(i-1)&1][x],f[(i-1)&1][y]+1);
f[(i+1)&1][x]=f[i&1][x];
f[(i+1)&1][y]=f[i&1][y];
//for(int j=1;j<=n;j++) cout<<f[i&1][j]<<" ";
//cout<<"\n";
}
for(int i=1;i<=n;i++){
if(i!=n){
if(f[m&1][i]!=INF) printf("%d ",f[m&1][i]);
else printf("-1 ");
}
else{
if(f[m&1][i]!=INF) printf("%d",f[m&1][i]);
else printf("-1");
}
}
cout<<"\n";
}
return 0;
}
京公网安备 11010502036488号