您的位置:首页 > 其它

hdu 3873(有节点保护的最短路)

2013-05-28 13:26 761 查看
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3873

思路:题目意思很简单,就是说如果没有攻占保护x的城市,就不能攻占,我们可以用pro[x]记录保护x的所有城市被攻占的最早时间,那么能到x的最短时间为pro[x]和到达x的最短路中的较大者 .dij入队过程中只把In[x](没有被包含的城市)入队 对于出队的x,它的最短时间已经确定,表示已经被占领,它所保护的城市的保护度减 1,一旦某个被保护的城市的保护度为零且已经到底(未占领,d[x]!=inf),就可以确定到达它的 最短时间(为max(pro[x],dist[x])),它也就到了入队的时机。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
#include<vector>
#include<algorithm>
using namespace std;
typedef long long LL;
typedef pair<LL,int>Pair;
#define inf (1ll)<<55
#define MAXN 3333

struct Node {
int v,w;
};
int In[MAXN];
LL dist[MAXN],pro[MAXN];
bool mark[MAXN];
vector<Node>Map[MAXN];
vector<int>vet[MAXN];
int n,m;

void Dijkstra(){
for(int i=1;i<=n;i++){ dist[i]=inf;pro[i]=0; }
dist[1]=0;
memset(mark,false,sizeof(mark));
priority_queue<Pair,vector<Pair>,greater<Pair> >Q;
Q.push(make_pair(dist[1],1));
while(!Q.empty()){
Pair pp=Q.top();
Q.pop();
int u=pp.second;
if(mark[u])continue;
mark[u]=true;
for(int i=0;i<vet[u].size();i++){
int v=vet[u][i];
In[v]--;
pro[v]=max(pro[v],dist[u]);
if(dist[v]!=inf&&In[v]==0){
dist[v]=max(dist[v],pro[v]);
Q.push(make_pair(dist[v],v));
}
}
for(int i=0;i<Map[u].size();i++){
int v=Map[u][i].v;
int w=Map[u][i].w;
if(dist[v]>dist[u]+w){
dist[v]=max(dist[u]+w,pro[v]);
if(In[v]==0){ Q.push(make_pair(dist[v],v)); }
}
}
}
}

int main() {
int _case,u,v,w,x;
scanf("%d",&_case);
while(_case--) {
scanf("%d%d",&n,&m);
for(int i=1; i<=n; i++) {
Map[i].clear();
vet[i].clear();
}
while(m--) {
scanf("%d%d%d",&u,&v,&w);
Node p;
p.v=v,p.w=w;
Map[u].push_back(p);
}
for(int i=1; i<=n; i++) {
scanf("%d",&In[i]);
for(int j=1; j<=In[i]; j++) {
scanf("%d",&x);
vet[x].push_back(i);
}
}
Dijkstra();
printf("%I64d\n",dist
);
}
return 0;
}


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