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 }