time limit per test:5.0 s
memory limit per test:64 MB
You live in a graph G, with N vertices and M edges. P of these vertices have gangsters living on them. You owe each gangster some money, given by the array C (of size P). You wish to travel from s to t. If you step within distance k of any gangster who you haven’t paid, you die. We define the length of a path as then number of edges it comprises. We define the distance of two nodes as the length of the shortest path connecting them. Further, we define the cost of travelling as the sum of gangster debts you pay off. Of course, you wish to minimise the cost of travelling from s to t without dying. Note that you may not die at s or t either.
Input
First line contains four integers, N N , , P P , and . (1 ≤ N, M, K ≤ 105, 1 ≤ P ≤ 10) ( 1 ≤ N , M , K ≤ 10 5 , 1 ≤ P ≤ 10 ) Second line contains P integers, the locations of the gangsters. Third line contains P integers, the array C (1 ≤ Ci ≤ 109) ( 1 ≤ C i ≤ 10 9 ) Each of the next M line contains two integers, xi and yi, which mean that there exists an edge between the nodes xi and yi. The last line contains two integers, s and t, the source and the target. It is guaranteed that a solution always exists.
Output
A single integer, the minimum cost of travelling from
s
s
to .
Example
Input
5 5 1 1
4
100
1 2
2 3
3 4
3 5
4 5
1 5
Output
100
Note
For the given example, the graph looks like
Note that the gangster is at distance 1 from the nodes 5 and 3, both of which must be visited.
题意:
给定N个点M条边的无向图,你欠P个海盗每个海盗Ci的钱,给出每个海盗的老巢,然后每个海盗能够控制距离他老巢距离<=k的所有点。k已经给出。求问至少要还多少钱才能从
s
s
走到点
题解:
枚举还钱的状态,bfs看看能不能从
s
s
走到,
记得用C++ 5.1.0其他版本貌似会TLE
虽然C++ 5.1.0跑了4991ms但是好歹过了
卡时间过的emmmmm
#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<queue>
#include<algorithm>
#include<cstdlib>
#define LiangJiaJun main
#define ll long long
#define MOD 100000000
#define INF 19991227000000LL
using namespace std;
int ne,h[100004],dis[100004];
int n,m,p,k;
struct edge{
int to,nt;
}e[300004];
int con[100004],P[14],c[14];
void add(int u,int v){
e[++ne].to=v;e[ne].nt=h[u];
h[u]=ne;
}
queue<int>q;
void trol(int tips,int x,int now,int k){
con[x]|=(1<<(tips-1));
if(now>=k)return ;
for(int i=h[x];i;i=e[i].nt){
if(con[e[i].to]&(1<<(tips-1)))continue;
trol(tips,e[i].to,now+1,k);
}
}
bool check(int x,int sta){
int sx=con[x];
for(int i=0;i<p;i++){
if((sx&(1<<i))&&(!(sta&(1<<i))))return 0;
}
return 1;
}
ll calc(int sta){
ll ans=0;
for(int i=1;i<=p;i++){
if(sta&(1<<(i-1)))ans+=c[i];
}
return ans;
}
bool bfs(int s,int t,int sta){
memset(dis,0,sizeof(dis));
if((!check(s,sta))||(!check(t,sta)))return 0;
while(!q.empty())q.pop();
q.push(s);
dis[s]=1;
while(!q.empty()){
int x=q.front();q.pop();
for(int i=h[x];i;i=e[i].nt){
if(!dis[e[i].to]&&check(e[i].to,sta)){
dis[e[i].to]=1;
q.push(e[i].to);
}
}
}
return (dis[t]!=0);
}
int w33ha(){
n=0;
memset(h,0,sizeof(h));
memset(con,0,sizeof(con));
for(int i=1;i<=p;i++)scanf("%d",&P[i]);
for(int i=1;i<=p;i++)scanf("%d",&c[i]);
for(int i=1;i<=m;i++){
int u,v;
scanf("%d%d",&u,&v);
add(u,v);
add(v,u);
}
for(int i=1;i<=p;i++)trol(i,P[i],0,k);
int S,T;
scanf("%d%d",&S,&T);
ll ans=INF;
for(int Sa=0;Sa<(1<<p);Sa++){
if(bfs(S,T,Sa))ans=min(ans,calc(Sa));
}
printf("%I64d\n",ans);
return 0;
}
int LiangJiaJun(){
while(scanf("%d%d%d%d",&n,&m,&p,&k)!=EOF)w33ha();
return 0;
}