zoukankan      html  css  js  c++  java
  • [bzoj1139]Wie

    1139: [POI2009]Wie

    Time Limit: 10 Sec  Memory Limit: 259 MB


    Description

    Byteasar has become a hexer - a conqueror of monsters. Currently he is to return to his hometown Byt
    eburg. The way home, alas, leads through a land full of beasts. Fortunately the habitants, forced to
    fight the monsters for centuries, have mastered the art of blacksmithery - they are now capable ofma
    king special swords that are very efficient against the beasts. The land Byteasar wanders throughis 
    quite vast: many towns lie there, and many roads connect them. These roads do not cross outside the 
    towns (mostly because some of them are underground passages).Byteasar has gathered all practicalinfo
    rmation about the land (all hexers like to know these things). He knows what kind of monsters hemay 
    come across each of the roads and how much time he needs to walk it down. He also knows in which vil
    lages there are blacksmiths and against what kinds of monsters the swords that they make work.Byteas
    ar wants to get back to Byteburg as soon as possible. As a hexer he is quite ashamed that he does no
    t know the best route, and that he has no sword on him at the moment. Help him find the shortest pat
    h to Byteburg such that whenever he could meet some king of monster, previously he would havea chanc
    e to get an appropriate sword to fight the beast. You need not worry about the number or weight of t
    he swords - every hexer is as strong as an ox, so he can carry (virtually) unlimited number of equip
    ment, swords in particular.
    大陆上有n个村庄,m条双向道路,p种怪物,k个铁匠,每个铁匠会居住在一个村庄里,你到了那个村庄后可以让他
    给你打造剑,每个铁匠打造的剑都可以对付一些特定种类的怪物,每条道路上都可能出现一些特定种类的怪物,每
    条道路都有一个通过所需要的时间,现在要从1走到n,初始的时候你没有剑,要求在经过一条道路的时候,对于任
    意一种可能出现在这条道路上的的怪物,你都有已经有至少一把剑可以对付他,求从1走到n的最短时间(打造剑不
    需要时间)

    Input

    第一行正整数 n m p k (1 ≤ n ≤ 200, 0 ≤ m ≤ 3 000, 1 ≤ p ≤ 13, 0 ≤ k ≤ n). 分别表示点数,边数
    ,剑/怪物的型号数,铁匠数。 
    接下来k行描述铁匠,格式如下: 所在点编号w,所能锻造的剑种类数q,升序给出q个1到p的不同的整数表示型号
    。 接下来m行描述边: 连接的顶点 x y,通过需要的时间t,路上的怪物数s,s个单调上升的1到p整数表示怪物型
    号。

    Output

    第一行输出最少时间。如果无法到达 输出-1

    Sample Input

    6 7 4 2
    2 1 2
    3 2 1 3
    1 2 2 0
    2 3 9 0
    1 4 2 1 2
    2 5 3 0
    4 5 5 2 2 3
    4 6 18 0
    5 6 3 2 1 2

    Sample Output

    24
     
    题解:状压+spfa
     1 #include <queue>
     2 #include <cstdio>
     3 #include <vector>
     4 #include <cstring>
     5 #include <algorithm>
     6 #define maxp 30
     7 #define maxn 300
     8 #define MAX_INT 0x7f7f7f7f
     9 using namespace std;
    10 bool vis[maxn][10000];
    11 int n,m,p,k,ans=MAX_INT;
    12 int dis[maxn][10000],t[maxn];
    13 struct tj{int t,v,sta;}tmp;
    14 struct statu{ int x,st; }temp;
    15 queue<statu> q;
    16 vector<tj> ve[maxn];
    17 void spfa(int s){
    18     int now=t[s];
    19     dis[s][now]=0,vis[s][now]=1;
    20     temp.x=s,temp.st=now,q.push(temp);
    21     while(!q.empty()){
    22         statu h=q.front();
    23         int x=h.x,st=h.st;
    24         q.pop(),vis[x][st]=0;
    25         if(dis[x][st|t[x]]>dis[x][st]){
    26             dis[x][st|t[x]]=dis[x][st];//可以松弛还没到到达的状态
    27             if(!vis[x][st|t[x]]) vis[x][st|t[x]]=1,q.push((statu){x,st|t[x]});
    28         }
    29         for(int i=0;i<ve[x].size();i++){//sta为这条边的状态,st为这个点的状态
    30             int v=ve[x][i].v,sta=ve[x][i].sta,ti=ve[x][i].t;
    31             if(dis[v][st]>dis[x][st]+ti&&(sta&st)==sta){
    32                 dis[v][st]=dis[x][st]+ti;
    33                 if(!vis[v][st]) q.push((statu){v,st}),vis[v][st]=1;
    34             }
    35         }
    36     }
    37     for(int i=0;i<=(1<<p);i++) ans=min(ans,dis[n][i]);
    38 }
    39 int main(){
    40     int x,y,l,k,d;
    41     memset(dis,0x7f,sizeof(dis));
    42     scanf("%d%d%d%d",&n,&m,&p,&d);
    43     for(int i=1;i<=d;i++){//铁匠
    44         scanf("%d%d",&x,&l);
    45         for(int j=1;j<=l;j++)
    46             scanf("%d",&k),t[x]|=1<<(k-1);
    47     }
    48     for(int i=1;i<=m;i++){
    49         tmp.sta=0;
    50         scanf("%d%d%d%d",&x,&y,&tmp.t,&l);
    51         for(int j=1;j<=l;j++)
    52             scanf("%d",&k),tmp.sta|=1<<(k-1);
    53         tmp.v=y;
    54         ve[x].push_back(tmp);
    55         tmp.v=x;
    56         ve[y].push_back(tmp);
    57     }
    58     spfa(1);
    59     if(ans!=MAX_INT) printf("%d
    ",ans);
    60     else printf("-1
    ");
    61     return 0;
    62 }
    63 /*
    64  6 7 4 2
    65  2 1 2
    66  3 2 1 3
    67  1 2 2 0
    68  2 3 9 0
    69  1 4 2 1 2
    70  2 5 3 0
    71  4 5 5 2 2 3
    72  4 6 18 0
    73  5 6 3 2 1 2
    74  */

     

  • 相关阅读:
    undefined reference to cv::imread(cv::String const&, int)
    ubuntu gcc 降级 适应matlab
    ubuntu 迅雷 XwareDesktop
    python 包 安装 加速 pip anaconda
    ubuntu classicmenu-indicator
    ubuntu 电源管理
    apue.h头文件(UNIX环境高级编程)
    ubuntu 12.04 下nginx安装步骤
    Ubuntu12.04 64bit 下安装VNC server
    TLD视觉跟踪算法
  • 原文地址:https://www.cnblogs.com/al76/p/9509188.html
Copyright © 2011-2022 走看看