ural 1500 Pass Licenses (dfs+bit)

来源:互联网 发布:java网上订餐系统视频 编辑:程序博客网 时间:2024/06/05 05:47

题意:

有n个十字路口(就是路的端点啦)、m条路、k中驾照,每一条路可属于若干种驾照(拥有

相应的驾照才能在这条路上通行)

求从编号为0的十字路口走到编号为1的十字路口,最少要有多少种驾照。


因为驾照数很少,可以用位来模拟相应的驾照。

然后枚举得到既能从0到1又最少的需求。


e[i][j]中为1的位代表这条路属于该驾照。


照着小伙伴的思路自己敲了一遍。。。。感觉结合位运算的搜索真是太神奇了!!!


#include<cstdio>#include<cstring>#include<iostream>#define INF 0x3f3f3f3fusing namespace std;int k,license[25],n;int vis[35];int e[35][35];void dfs(int s,int now){    vis[s]=1;    if(s==1) return;    for(int i=0;i<n;i++)    {        if((e[s][i]&now) && !vis[i])            dfs(i,now);    }}int main(){    int m,v1,v2,c,tmp,now,ans,cato,cnt;    while(scanf("%d%d%d",&k,&n,&m)!=EOF)    {        memset(e,0,sizeof(e));        for(int i=0;i<m;i++)        {            scanf("%d%d%d",&v1,&v2,&c);            e[v1][v2]=(e[v1][v2]|(1<<c));            e[v2][v1]=e[v1][v2];        }        ans=INF;        int i;        for(i=0;i<(1<<k);i++)        {            tmp=i;            cnt=0;            while(tmp)     //剪枝。大于已经求得的            {               //符合要求所需的驾照数就不必再dfs了                if(tmp&1)                    cnt++;                tmp=tmp>>1;            }            if(cnt>=ans) continue;            memset(vis,0,sizeof(vis));            now=i;            dfs(0,now);            if(vis[1])   //如果能够到1            {                ans=0,cato=0;                while(now)                {                    if(now&1)                    {                        license[ans++]=cato;                    }                    now>>=1;                    cato++;     //驾照的种类编号                }            }        }        printf("%d\n",ans);        for(int i=0;i<ans-1;i++)            printf("%d ",license[i]);        printf("%d\n",license[ans-1]);    }    return 0;}





0 0