Ural 1500Pass Licenses(状态压缩dfs)
2014-01-12 14:40
411 查看
有k种执照,n个点,m条路,每条路都属于一些执照(拥有指定执照才能走)
求从0走到1 最少需要多少执照
枚举 0到k-1 二进制的每一位代表是否拥有该执照,那么只用枚举状态0~(2^(k-1)-1)即可。表示执照是否存在的状态,然后就是dfs暴搜了,在搜的过程中,如果这个状态的需要执照个数>=可行解的最小值,那么不需要搜索,直接换另一种状态。详见代码:
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
int mp[35][35];
int visi[35];
int rans[35];
int n;
void dfs(int p,int c)
{
visi[p]=1;
if(p==1) return;
for(int i=0;i<n;i++)
{
if((c&mp[p][i])&&!visi[i]) //可以到达
dfs(i,c);
}
}
int main()
{
int m,k,i;
int a,b,c;
while(cin>>k>>n>>m) //n个结点,m条路,k种护照
{
memset(mp,0,sizeof(mp));
while(m--)
{
scanf("%d%d%d",&a,&b,&c);
mp[a][b]=(mp[a][b]|(1<<c));
mp[b][a]=mp[a][b];
}
//下面就是枚举所有的状态了
int ans=1e9; //>=2^20即可
int tmp,cnt,q;
int res;
//tmp记录状态 cnt记录最小的满足条件个数
for(i=0;i<(1<<k);i++)
{
tmp=i,cnt=0;
q=tmp;
while(tmp) //个数>=ans的不要
{
if(tmp&1)
cnt++;
tmp>>=1;
}
if(cnt>=ans) continue;
tmp=q;
memset(visi,0,sizeof(visi));
dfs(0,tmp);
if(visi[1])
{
ans=0;
res=tmp;
while(tmp)
{
if(tmp&1)
ans++;
tmp>>=1;
}
}
}
int t=0;
q=0;
while(res)
{
if(res&1)
rans[t++]=q;
res>>=1;
q++;
}
cout<<t<<endl;
cout<<rans[0];
for(i=1;i<t;i++)
cout<<" "<<rans[i];
cout<<endl;
}
return 0;
}
/*
3 3 3
0 2 0
0 2 1
1 2 2
*/
求从0走到1 最少需要多少执照
枚举 0到k-1 二进制的每一位代表是否拥有该执照,那么只用枚举状态0~(2^(k-1)-1)即可。表示执照是否存在的状态,然后就是dfs暴搜了,在搜的过程中,如果这个状态的需要执照个数>=可行解的最小值,那么不需要搜索,直接换另一种状态。详见代码:
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
int mp[35][35];
int visi[35];
int rans[35];
int n;
void dfs(int p,int c)
{
visi[p]=1;
if(p==1) return;
for(int i=0;i<n;i++)
{
if((c&mp[p][i])&&!visi[i]) //可以到达
dfs(i,c);
}
}
int main()
{
int m,k,i;
int a,b,c;
while(cin>>k>>n>>m) //n个结点,m条路,k种护照
{
memset(mp,0,sizeof(mp));
while(m--)
{
scanf("%d%d%d",&a,&b,&c);
mp[a][b]=(mp[a][b]|(1<<c));
mp[b][a]=mp[a][b];
}
//下面就是枚举所有的状态了
int ans=1e9; //>=2^20即可
int tmp,cnt,q;
int res;
//tmp记录状态 cnt记录最小的满足条件个数
for(i=0;i<(1<<k);i++)
{
tmp=i,cnt=0;
q=tmp;
while(tmp) //个数>=ans的不要
{
if(tmp&1)
cnt++;
tmp>>=1;
}
if(cnt>=ans) continue;
tmp=q;
memset(visi,0,sizeof(visi));
dfs(0,tmp);
if(visi[1])
{
ans=0;
res=tmp;
while(tmp)
{
if(tmp&1)
ans++;
tmp>>=1;
}
}
}
int t=0;
q=0;
while(res)
{
if(res&1)
rans[t++]=q;
res>>=1;
q++;
}
cout<<t<<endl;
cout<<rans[0];
for(i=1;i<t;i++)
cout<<" "<<rans[i];
cout<<endl;
}
return 0;
}
/*
3 3 3
0 2 0
0 2 1
1 2 2
*/
相关文章推荐
- ural 1500 Pass Licenses --- 状态压缩dfs
- 【算法设计与数据结构】URAL 1152.False Mirrors(状态压缩dp+dfs)
- ZOJ 2412 Farm Irrigation(DFS+状态压缩)
- POJ2743Mobile Computing[DFS 状态压缩]
- hdu 3920 状态压缩dp+dfs
- uva 11195(状态压缩+dfs)
- USACO Section 3.4 Raucous Rockers(状态压缩或DFS)
- poj 1753 Flip Game(bfs状态压缩 或 dfs枚举)
- SRM 628 DIV2 1000 CandleTimerEasy 状态压缩+DFS
- codeforces B - Preparing Olympiad(dfs或者状态压缩枚举)
- LightOJ1018- Brush (IV) -状态压缩,DFS
- USACO-Section 2.1 Healthy Holsteins (状态压缩DFS)
- 杭电2553_N皇后(直接DFS解法和二进制状态压缩解法)——java
- [poj3740]Easy Finding_状态压缩_dfs
- Codeforces Round #108 (Div. 2)——状态压缩DP+spfa+dfs——Garden
- uva1507(状态压缩+dfs)
- HDU 4272LianLianKan 2012长春网络赛F题(思维) 暴力,dfs可以水过,正解是状态压缩dp
- poj 1691 Painting A Board (DFS/状态压缩DP)
- hdu 3681 Prison Break (状态压缩dp/dfs + bfs)
- dfs。。状态压缩dp poj3411