首页 > 其他分享 >P3489 [POI2009]WIE-Hexer 题解

P3489 [POI2009]WIE-Hexer 题解

时间:2023-03-23 22:33:09浏览次数:34  
标签:WIE ab int 题解 tt u1 P3489 include dis

一、题目描述:

  大陆上有 n 个村庄,m 条双向道路,p 种怪物,k 个铁匠,铁匠都在一个村庄里,他可会给你打造他所能打造的所有剑,特定的剑可以对付特定的怪物,每条道路上都可能出现一些特定的怪物,每条道路有一个通过时间。现在要从 1 走到 n,初始的时候你没有剑,要求在经过一条道路的时候,对于任意一种出现在这条道路上的的怪物,你已经有一把特定的剑可以对付他,求从 1 走到 n 的最短时间(打造剑不需要时间)。如果不能到达 n 则输出 -1。数据范围:1<=n<=200,0<=m<=3000,1<=p<=13,0<=k<=n


二、做题思路

  p这么小,果断状压存状态。设 dp[i][j] 表示走到第 i 个点状态为 j 的最短路,跑一遍 dij 就可以了。(看起来挺简单,实际上我还是写了很久qwq)


三、完整代码:

#include<iostream>
#include<cstring>
#include<queue>
#define N 210
#define M 3010
using namespace std;
int dis[N][(1<<13)+10],ab[N];
int n,m,p,k,u1,v1,w1,s1,t1,n1;
struct EDEG{
    int v,w,gs,nxt;
}e[M*2];
int head[N],cnt;
void add(int u,int v,int w,int gs)
{
    e[++cnt].nxt=head[u];head[u]=cnt;
    e[cnt].v=v;e[cnt].w=w;e[cnt].gs=gs;
}
struct node{
    int val,status,dis;
    bool operator < (const node &t)const{
        return t.dis<dis;
    }
};
priority_queue <node> q;
void dij(int s)
{
    dis[1][0]=0;
    q.push({1,0,0});
    while(!q.empty())
    {
        node tt=q.top();q.pop();
        int u=tt.val,d=tt.status;
        dis[u][d|ab[u]]=dis[u][d];d|=ab[u];
        for(int i=head[u];i!=-1;i=e[i].nxt)
            if((e[i].gs&d)==e[i].gs)
                if(dis[e[i].v][d]>dis[u][d]+e[i].w)
                {
                    dis[e[i].v][d]=dis[u][d]+e[i].w;
                    q.push({e[i].v,d,dis[e[i].v][d]});
                }
    }
}
int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);cout.tie(0);
    cin>>n>>m>>p>>k;
    for(int i=1;i<=k;i++)
    {
        cin>>u1>>s1;
        for(int j=1;j<=s1;j++)
        {
            cin>>v1;
            ab[u1]|=(1<<(v1-1));
        }
    }
    memset(head,-1,sizeof(head));
    memset(dis,0x3f,sizeof(dis));
    for(int i=1;i<=m;i++)
    {
        w1=0;
        cin>>u1>>v1>>t1>>s1;
        for(int j=1;j<=s1;j++)
            cin>>n1,w1|=(1<<(n1-1));
        add(u1,v1,t1,w1);
        add(v1,u1,t1,w1);
    }
    dij(1);
    int minn=1000000000;
    for(int i=0;i<=(1<<13);i++)
        minn=min(minn,dis[n][i]);
    if(minn!=1000000000)
        cout<<minn<<'\n';
    else    cout<<-1<<'\n';
    return 0;
}

  怎么说,我的代码就是好看qwq。


四、写题心得:

  今天学了分层图,感觉挺简单的,实际上还是挺考思维的。这个题有点难度又是自己写出来的,所以真的还是很高兴,加油!

 

标签:WIE,ab,int,题解,tt,u1,P3489,include,dis
From: https://www.cnblogs.com/yhy-trh/p/17249759.html

相关文章

  • P4221 [WC2018]州区划分 题解
    题目链接题目描述给出\(n\)个城市,\(m\)条边,一个划分合法当且仅当所有划分中的点集和集合中点之间存在的边集所构成的图不构成欧拉回路且联通。定义一个点集的值为......
  • 【ACM算法竞赛日常训练】DAY1题解与分析
    DAY1共四题:月月查华华的手机:https://ac.nowcoder.com/acm/problem/23053RinneLovesEdges:https://ac.nowcoder.com/acm/problem/22598逆序对:https://ac.nowcoder.com......
  • CF1630E 题解
    题意传送门一个长度为$n$的环状序列${a_i}$,其中的数值满足$1\leqa_i\leqn$,序列中可能有相等的数。序列${a_i}$的一个排列和另外一个排列本质相同,当且......
  • LDAP - 题解【模拟】
    题面该题为CCF-CSP认证考试真题,试题编号为202303-3。我参加了这次CSP认证(虽然说认证成绩没有达到预期emmm),原题链接见:202303-3。下面搬运题面如下:题目背景西西艾弗岛运营......
  • Nacos 2.2.1 版本下载启动报错问题解决
    先上错误问题这个报错我在网上找了~~~每个人都在说五花八门的,接近真相但却不是!!!!!接下来由我补充nacos-server-2.2.1\nacos\bin\startup.cmd文件修......
  • 单链表OJ题解析1
    1.移除链表元素题目链接题目描述 解题思路这道题较好的解法是创建一个新链表,把不等于val的节点链接到一起,然后返回新链表的头结点structListNode*removeEle......
  • 关于airtest无法连接模拟器问题解决思路
    背景:死活打开airtestIDE死活识别不了夜神模拟器。官网下载最新airtest之后,自己电脑Androidsdk是最新的版本,也用adbversion检查了本地版本、夜神模拟器版本。确实发现夜......
  • 微信小程序之wx.getLocation再次授权问题解决
    首先,在page外定义一个公共函数用于发送获取位置的请求vargetLocation=function(that){wx.getLocation({type:'wgs84',success:function(res){......
  • SuperMicro X10SDV 主板 + ESXi 8.0 不认网卡的问题解决
    问题描述超微主板X10SDV:17cm*17cm板载2个万兆电口[email protected](最高2133MHz、最多32GB*4=128GB)内存槽:注意:只支持2R,不支持淘宝上的诸如三星DDR4......
  • Edu Round 板刷计划 1. Educational Codeforces Round 1 题解
    ChangeLog:2023.03.21开坑。A-TrickySum简单题。注意到\(n\)以内\(2\)的幂次只有\(O(\logn)\)个,因此只要先算出\(1\)~\(n\)里所有数的和再减去\(2\)......