[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
*/

总结

同余最短路的一般套路。

posted @ 2020-11-28 18:01  基地AI  阅读(119)  评论(0编辑  收藏  举报