标签:des style blog http color os io for ar
先上题目:
input | output |
---|---|
3 3 3 0 2 0 0 2 1 1 2 2 |
2 0 2
|
题意:给出n个点m条边(无向),有k种驾照,每条边如果想通过的话需要某一种驾照,问你从0号点到1号点最少需要多少种驾照,并把它们输出。
做法:状态压缩然后暴力检查是否合法,记录最少需要多少中驾照。
s[i][j]表示从i->j的话有哪几种可以用的驾照。然后枚举不同的驾照组合,找到最少需要的数目以后输出即可。
上代码:
1 #include <cstdio> 2 #include <cstring> 3 #include <utility> 4 #include <set> 5 #define MAX 32 6 #define MK(x,y) (make_pair(x,y)) 7 using namespace std; 8 9 int s[MAX][MAX]; 10 bool vis[MAX]; 11 int k,n,m; 12 13 bool dfs(int u,int caps) { 14 vis[u]=1; 15 if(u==1) return 1; 16 for(int i=0;i<n;i++){ 17 if(!vis[i] && (caps&s[u][i])){ 18 if(dfs(i,caps)) return 1; 19 } 20 } 21 return 0; 22 } 23 24 int main() { 25 int u,v,cap,ans,caps,f; 26 //freopen("data.txt","r",stdin); 27 while(scanf("%d %d %d",&k,&n,&m)!=EOF) { 28 memset(s,0,sizeof(s)); 29 for(int i=0;i<m;i++){ 30 scanf("%d %d %d",&u,&v,&cap); 31 if(u==v) continue; 32 s[u][v]|=(1<<cap); 33 s[v][u]|=(1<<cap); 34 } 35 ans=k+1; 36 caps=0; 37 for(int i=1;i<(1<<k);i++){ 38 int cnt=0; 39 for(int j=0;j<k;j++){ 40 if(i&(1<<j)) cnt++; 41 } 42 if(cnt>=ans) continue; 43 memset(vis,0,sizeof(vis)); 44 if(dfs(0,i)){ 45 ans=cnt; 46 caps=i; 47 } 48 } 49 printf("%d\n",ans); 50 f=0; 51 for(int i=0;caps>0;caps>>=1,i++){ 52 if(caps&1){ 53 if(f++) printf(" "); 54 printf("%d",i); 55 } 56 } 57 printf("\n"); 58 } 59 return 0; 60 }
标签:des style blog http color os io for ar
原文地址:http://www.cnblogs.com/sineatos/p/3940235.html