zoukankan      html  css  js  c++  java
  • SGU -1500

    先上题目:

    1500. Pass Licenses

    Time limit: 2.5 second
    Memory limit: 64 MB
    A New Russian Kolyan believes that to spend his time in traffic jams is below his dignity. This is why he had put an emergency flashlight upon the roof of his Hummer and had no problems until a recent decision of the city administration. Now each street of the city belongs to one or several categories, and a driver must have a separate license in order to use an emergency flashlight in the streets of each category. If a street belongs to several categories, it is sufficient to have a license only for one of these categories. For each category, a license is issued by a separate city official. Although these officials are different, they accept bribes of the same amount for giving a license. Help Kolyan to find a way from his home to work such that he can go this way with his flashlight turned on and having spent the minimal amount of money for bribes.

    Input

    The input contains the street plan in the following format. There are integers KN, and M in the first line, where K is the number of street categories (1 ≤ K ≤ 20), N is the number of crossroads (2 ≤ N ≤ 30), and M is the number of descriptions of street segments between crossroads.
    Each of the next M lines describes a street segment by three integers V1 V2 C, where V1 and V2 are the numbers of the crossroads limiting this segment, and C is its category. Crossroads are numbered from 0 to N – 1, categories are numbered from 0 to K – 1. For any pair of crossroads no two segments of the same category connect these crossroads.

    Output

    Output in the first line the minimal number of licenses necessary for going from the crossroad 0 (Kolyan's home) to the crossroad 1 (Kolyan's work) with an emergency flashlight turned on.
    In the second line, give the list of categories for which licenses must be obtained. The numbers should be separated with spaces. It is guaranteed that such list is always exist.

    Sample

    inputoutput
    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
    ",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("
    ");
    58     }
    59     return 0;
    60 }
    /*SGU 1500*/
  • 相关阅读:
    自增长主键Id的另类设计
    Android 混淆那些事儿
    H5 和移动端 WebView 缓存机制解析与实战
    快速上手 Kotlin 的 11 招
    教你 Debug 的正确姿势——记一次 CoreMotion 的 Crash
    小程序组件化框架 WePY 在性能调优上做出的探究
    基于 TensorFlow 在手机端实现文档检测
    HTTPS 原理浅析及其在 Android 中的使用
    Bugly 多渠道热更新解决方案
    Swift 对象内存模型探究(一)
  • 原文地址:https://www.cnblogs.com/sineatos/p/3940235.html
Copyright © 2011-2022 走看看