题目:http://lightoj.com/login_main.php?url=volume_showproblem.php?problem=1406
题意:有n个城市,m条路,刺客要去这n个城市,但刺客经过的城市别的刺客就不会再经过,问最少几个刺客可以走完这n个城市
想清楚状态后就很容易
先dfs将所有能一次走到的状态跑出来
然后状压dp
将当前状态拆分,再利用异或来选择和当前相反的路径
#include<iostream> #include<cstdio> #include<cstring> #include<string> #include<cmath> #include<algorithm> #include<vector> #include<queue> #include<stack> #include<map> #include<set> using namespace std; int a[20][20]; bool can[1<<15][15]; int dp[1<<15]; int n,m; void dfs(int x,int now) { if (can[x][now]) return; can[x][now]=1; dp[x]=1; for(int i=0;i<n;i++) if (a[now][i]) dfs(x|1<<i,i); } int main() { int T; scanf("%d",&T); for(int ca=1;ca<=T;ca++) { scanf("%d%d",&n,&m); memset(a,0,sizeof(a)); for(int i=1;i<=m;i++) { int x,y; scanf("%d%d",&x,&y); x--; y--; a[x][y]=1; } memset(can,0,sizeof(can)); memset(dp,0x3f,sizeof(dp)); dp[0]=0; for(int i=0;i<n;i++) dfs(1<<i,i); int tot=1<<n; for(int i=0;i<tot;i++) for(int j=i;j;j=(j-1)&i) dp[i]=min(dp[i],dp[j]+dp[i^j]); printf("Case %d: %d ",ca,dp[tot-1]); } return 0; }