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

题目链接: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])),它也就到了入队的时机。

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<queue>
 5 #include<vector>
 6 #include<algorithm>
 7 using namespace std;
 8 typedef long long LL;
 9 typedef pair<LL,int>Pair;
10 #define inf (1ll)<<55
11 #define MAXN 3333
12 
13 struct Node {
14     int v,w;
15 };
16 int In[MAXN];
17 LL dist[MAXN],pro[MAXN];
18 bool mark[MAXN];
19 vector<Node>Map[MAXN];
20 vector<int>vet[MAXN];
21 int n,m;
22 
23 void Dijkstra(){
24    for(int i=1;i<=n;i++){ dist[i]=inf;pro[i]=0; }
25    dist[1]=0;
26    memset(mark,false,sizeof(mark));
27    priority_queue<Pair,vector<Pair>,greater<Pair> >Q;
28    Q.push(make_pair(dist[1],1));
29    while(!Q.empty()){
30       Pair pp=Q.top();
31       Q.pop();
32       int u=pp.second;
33       if(mark[u])continue;
34       mark[u]=true;
35       for(int i=0;i<vet[u].size();i++){
36          int v=vet[u][i];
37          In[v]--;
38          pro[v]=max(pro[v],dist[u]);
39          if(dist[v]!=inf&&In[v]==0){
40             dist[v]=max(dist[v],pro[v]);
41             Q.push(make_pair(dist[v],v));
42          }
43       }
44       for(int i=0;i<Map[u].size();i++){
45          int v=Map[u][i].v;
46          int w=Map[u][i].w;
47          if(dist[v]>dist[u]+w){
48             dist[v]=max(dist[u]+w,pro[v]);
49             if(In[v]==0){ Q.push(make_pair(dist[v],v)); }
50          }
51       }
52    }
53 }
54 
55 
56 int main() {
57     int _case,u,v,w,x;
58     scanf("%d",&_case);
59     while(_case--) {
60         scanf("%d%d",&n,&m);
61         for(int i=1; i<=n; i++) {
62             Map[i].clear();
63             vet[i].clear();
64         }
65         while(m--) {
66             scanf("%d%d%d",&u,&v,&w);
67             Node p;
68             p.v=v,p.w=w;
69             Map[u].push_back(p);
70         }
71         for(int i=1; i<=n; i++) {
72             scanf("%d",&In[i]);
73             for(int j=1; j<=In[i]; j++) {
74                 scanf("%d",&x);
75                 vet[x].push_back(i);
76             }
77         }
78         Dijkstra();
79         printf("%I64d\n",dist[n]);
80     }
81     return 0;
82 }
View Code

 

 

posted @ 2013-05-28 13:26  ihge2k  阅读(879)  评论(0编辑  收藏  举报