您的位置:首页 > 其它

dlutoj 1081 巧斗雷震子

2014-03-13 18:46 162 查看


Description

因为下雨的关系,小朋友被困在综一了,W先生知道后,立即前往营救,一个N个点的图,一共M条边,边是双向的,但是因为下雨和打雷的关系,每个端点上都有雷震子镇守,想通过该点,必须被雷震子雷劈,每个雷震子都有一个雷劈伤害值,W先生很幸运,他有F张IP(挨劈)卡,一张IP卡可以抵消一次雷劈伤害,但是有个要求,不能在X和Y点都使用IP卡,也就是在X,Y两点中的最多使用一张IP卡,W先生要从S 点前往 T点,又想自己的雷劈伤害值总和最小,现在W先生问你,他的最低的雷劈伤害值总和是多少。


Input

多组case,以eof结尾

第一行 N表示点的数量(N<=200),M表示边的数量(M<=N*N)

接下来M行,每行两个数 : u ,v 表示 u点和v点是连接的。

接下来 一行 N 个数 : 第i个数 表示 i号点 雷震子的雷劈伤害值为 ci,1<=ci<=1000。

接下来 一行 :S,T (1<=S,T<=N)

接下来 一行 :X , Y, F (1<=X<Y<=N, F<=50)


Output

每个case输出一行,最低的雷劈伤害总和是多少。(当无法到达T时输出-1)。


Sample Input

5 41 22 33 44 51 5 4 9 11 52 4 2


Sample Output

7

最初看起来是一道最短路,仔细想了一想,因为是点上有权值而不是每条边有权值,

所以用优先队列的bfs做出来了。队列的元素是结构体,存当前节点和走到当前节点所用的权值。

先把起点放入队列,把与起点相连的所有点全部加上权值放入队列。

由于每次队列顶都是权值最小的,所以该点能走到的节点一定不会有其他点能走到且比当前点更短。

因为这个所以我们可以bfs。

每次加入一个节点,都用一个数组把当前节点的前驱记录下来。

最后从终点遍历,记录走过路径所经过的节点,

把最大的F个点去掉(注意X,Y的处理),其余点的权值之和就是所求的答案。

#include<iostream>

#include<cstring>

#include<queue>

#include<vector>

#include<algorithm>

using namespace std;

const int maxn=205;

bool ok[maxn][maxn],OK[maxn];

int a[maxn],c[maxn];

int N,M,S,T,X,Y,F;

struct xx

{

int i,n;

friend bool operator < (xx a,xx b)

{

return a.n>b.n;

}

};

bool cmp(int i,int j)

{

return a[i]>a[j];

}

int main()

{

while(cin>>N>>M)

{

int i,j,ans=0;

bool ok1=1;

priority_queue<xx>bfs;

memset(ok,0,sizeof(ok));

memset(a,0,sizeof(a));

memset(c,0,sizeof(c));

memset(OK,0,sizeof(OK));

while(M--)

{

int u,v;

cin>>u>>v;

ok[u][v]=ok[v][u]=1;

}

for(i=1;i<=N;++i)

cin>>a[i];

cin>>S>>T>>X>>Y>>F;

bfs.push((xx){S,0});

while(!bfs.empty())

{

int i=bfs.top().i,n=bfs.top().n;

bfs.pop();

for(int k=1;k<=N;++k)

if(ok[i][k]&&!OK[k])

{

OK[k]=1;

bfs.push((xx){k,n+a[k]});

c[k]=i;

}

}

i=T;

int o=0;

int XX[maxn];

XX[o++]=T;

while(i!=S)

{

XX[o++]=c[i];

i=c[i];

}

sort(XX,XX+o,cmp);

for(i=0;i<o;++i)

{

if((XX[i]==X||XX[i]==Y)&&ok1)

{

ok1=0; F--;

}

else if((XX[i]==X||XX[i]==Y)&&ok1==0)

{

ans+=a[XX[i]];

}

else if(F)

{

F--;

}

else ans+=a[XX[i]];

}

cout<<ans<<endl;

}

return 0;

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: