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;
}
相关文章推荐
- dlutoj 1081 Prufer 序列
- ZOJ1081 Points Within
- hdu 1081 To The Max最大连续子串和
- hdu 1081 To The Max ****poj 1050(最大子矩阵和)DP
- HDU 1081 最大子矩阵
- hdu 1081 To The Max (动态规划)
- hdu——1081(二维最大连续和)
- hdu 1081 To The Max
- 题目1081:递推数列
- HDU 1081 To The Max
- hdu 1081 To The Max(最大子矩阵和)
- PAT 1081. Rational Sum (20)
- 【九度OJ】1081【矩阵】【快速幂】
- Ural1081 (dp)
- HDU1081_To The Max【矩阵压缩】
- [BZOJ 1081] [SCOI2005] 超级格雷码 【找规律】
- HDU - 1081 To The Max
- URAL1081——DP—— Binary Lexicographic Sequence
- HDU 1081 To The Max 暴力模拟O(n^4) dp优化O(n^3)
- PAT 1081. Rational Sum (20)