• [题解] [JSOI2014] 骑士游戏


    题面

    题解

    有一个很简单的 DP 式

    [f[i] = min(k[i], s[i] + sum f[j]) ]

    其中 (j) 是普攻 (i) 后产生的小怪编号
    但是这样转移可能有环
    我们考虑使用最短路转移, 对于一对 ((i, j)) 连边 (i o j)
    然后初始化每个点都为法术攻击, 如果当前点被更新了, 就拿他去更新他的前驱

    #include <algorithm>
    #include <iostream>
    #include <cstring>
    #include <cstdio>
    #include <vector>
    #include <queue>
    typedef long long ll; 
    const int N = 2e5 + 5;
    const int M = 1e6+ 5; 
    using namespace std;
    
    int n, head[N], headf[N], cnt, tot;
    ll s[N], k[N], dis[N];
    struct edge { int to, nxt; } e[M], fe[M]; 
    bool vis[N];
    vector<int> t[N], ft[N]; 
    queue<int> q; 
    
    template < typename T >
    inline T read()
    {
        T x = 0, w = 1; char c = getchar();
        while(c < '0' || c > '9') { if(c == '-') w = -1; c = getchar(); }
        while(c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar();
        return x * w; 
    }
    
    inline void adde(int u, int v)
    {
        e[++cnt] = (edge) { v, head[u] }, head[u] = cnt;
        fe[++tot] = (edge) { u, headf[v] }, headf[v] = cnt; 
    }
    
    ll SPFA()
    {
        for(int i = 1; i <= n; i++)
    	dis[i] = k[i], q.push(i), vis[i] = 1;
        ll tmp; 
        while(!q.empty())
        {
    	int u = q.front(); q.pop();
    	vis[u] = 0, tmp = 0; 
    /*	for(int v, i = head[u]; i; i = e[i].nxt)
    	    v = e[i].to, tmp += dis[v];
    	tmp += s[u];
    	if(tmp < dis[u])
    	{
    	    dis[u] = tmp; 
    	    for(int f, i = headf[u]; i; i = fe[i].nxt)
    	    {
    		f = fe[i].to;
    		if(!vis[f]) q.push(f), vis[f] = 1; 
    	    }
    	}
    */
    	for(int i = 0; i < t[u].size(); i++)
    	    tmp += dis[t[u][i]];
    	tmp += s[u];
    	if(dis[u] <= tmp) continue;
    	dis[u] = tmp;
    	for(int i = 0; i < ft[u].size(); i++)
    	    if(!vis[ft[u][i]]) vis[ft[u][i]] = 1, q.push(ft[u][i]); 
        }
        return dis[1]; 
    }
    
    int main()
    {
        n = read <int> ();
        for(int num, i = 1; i <= n; i++)
        {
    	s[i] = read <ll> (), k[i] = read <ll> (), num = read <int> (); 
    	for(int v, j = 1; j <= num; j++)
    	    v = read <int> (), adde(i, v), t[i].push_back(v), ft[v].push_back(i); 
        }
        printf("%lld
    ", SPFA()); 
        return 0; 
    }
    
  • 相关阅读:
    selenium 定制启动chrome的参数
    简单删除我的电脑里的wps云文档图标
    linux下设置git代理访问.
    关于要python爬虫你需要的一些网址和信息[待补充]
    在windows10 Linux (centos7)中安装go golang (够浪) 并测试运行
    ansible-cmdb 解析(ansible all -m setup )收集过来的信息并以html方式显示。
    使用python开发ansible自定义模块的简单案例
    关于openstack 网络相关的文章收集
    kubernets安装rabbitmq集群.
    centos7安装jenkins..
  • 原文地址:https://www.cnblogs.com/ztlztl/p/12296559.html
Copyright © 2020-2023  润新知