zoukankan      html  css  js  c++  java
  • [noi.ac 模拟赛9] A.出征准备(同余最短路)

    题目

    题目描述

    dkw 的剑需要 (t) 点能量, 黑市有 (n) 种充能水晶, 每种充能水晶有它的能量值 (V_i)

    dkw 有无限的钱, 可以买任意种水晶任意个(不能买负数个)。

    由于 dkw 的剑必须刚好充满能量才能使用,所以你需要回答他是否存在一种方案,刚好充满 dkw 的剑的能量。

    输入格式

    第一行是一个 (T) , 代表测试数据组数

    对于每组测试数据, 第一行有两个整数 (n, t)
    接下来 (n) 行, 每行一个整数, (V_i)

    输出格式

    对于每组测试数据, 如果能, 输出 Possible ; 否则输出 Impossible

    数据范围

    (1≤T≤10, 1≤n≤50, 1≤t≤10^{18}, 0≤V_i≤10^4)

    题解

    (V_1)({V}) 中最小的。设 (dist[i]) 表示经过 (V_2,...,V_n) 的加法,最小的 (p equiv i pmod{V_1})。跑一个同余最短路就好了。

    (m=Vn),时间复杂度 (O(Tm log m))

    代码

    Talk is cheap.Show me the code.

    #include<bits/stdc++.h>
    #define int long long
    #define mp make_pair
    #define fi first
    #define se second
    using namespace std;
    inline int read() {
        int x = 0, f = 1; char ch = getchar();
        while(ch<'0' || ch>'9') { if(ch=='-') f=-1; ch=getchar(); }
        while(ch>='0'&&ch<='9') { x=(x<<3)+(x<<1)+(ch^48); ch=getchar(); }
        return x * f;
    }
    typedef pair<int,int> PII;
    const int N = 1e4+7;
    int t,n,cnt;
    int V[N],head[N];
    struct Edge {
    	int next,to,w;
    }edge[N*50];
    inline void add(int u,int v,int w) {
    	edge[++cnt] = (Edge)<%head[u],v,w%>;
    	head[u] = cnt;
    }
    int dist[N];	//dist[i] 最小的 p≡i(mod V[1]) 
    bool vis[N];
    void Dijkstra() {
    	memset(dist, -1, sizeof(dist));
    	memset(vis, 0, sizeof(vis));
    	priority_queue<PII> q;
    	dist[0] = 0;
    	q.push(mp(-dist[0],0));
    	while(!q.empty()) {
    		int u = q.top().se;
    		q.pop();
    		if(vis[u]) continue;
    		vis[u] = 1;
    		for(int i=head[u];i;i=edge[i].next) {
    			int v = edge[i].to, w = edge[i].w;
    			if(dist[u]+w > t) continue;
    			if(dist[v]==-1 || dist[v]>dist[u]+w) {
    				dist[v] = dist[u] + w;
    				q.push(mp(-dist[v],v));
    			}
    		}
    	}
    }
    void work() {
    	memset(head, 0, sizeof(head));
    	cnt = 0;
    	n = read(), t = read();
    	for(int i=1;i<=n;++i) V[i] = read();
    	sort(V+1,V+1+n);
    	for(int i=0;i<V[n];++i) {
    		for(int j=1;j<n;++j) {
    			add(i,(i+V[j])%V[n],V[j]);
    		}
    	}
    	Dijkstra();
    	if(dist[t%V[n]]==-1 || dist[t%V[n]]>t) puts("Impossible");
    	else puts("Possible");
    }
    signed main()
    {
    	int T = read();
    	while(T--) work();
        return 0;
    }
    /*
    1
    4 78  
    12
    5
    7
    9
    
    Possible
    */
    

    总结

    同余最短路的一般套路。

  • 相关阅读:
    C# FileStream 文件复制
    DataSnap Server 客户端调用 异常
    抛出异常 exception
    RAD Tokyo 10.2.2
    delphi ios info.plist
    sql 日期格式
    sql server 2014登录账号
    sql server导入excel数据
    dev16 cxgrid 在DLL里报0地址错
    sql server 查看所有表记录数
  • 原文地址:https://www.cnblogs.com/BaseAI/p/14053435.html
Copyright © 2011-2022 走看看