您的位置:首页 > 其它

HDU 3873 Invade the Mars Dijkstra变种

2016-11-24 22:05 405 查看
Invade the Mars
Time Limit: 5000/2000 MS (Java/Others)    Memory Limit: 365768/165536 K (Java/Others)
Total Submission(s): 2136    Accepted Submission(s): 623

Problem Description
It's now the year 21XX,when the earth will explode soon.The evil U.S. decided to invade the Mars to save their lives.
But the childlike Marsmen never keeps any army,because war never take place on the Mars.So it's very convenient for the U.S. to act the action.
Luckily,the Marsmen find out the evil plan before the invadation,so they formed a defense system.The system provides enchantment for some citys,and the enchantment generator for city A maybe set in city B,and to make things worse,both city B and C and more will provide echantment for city A.
The satelite of U.S. has got the map of the Mars.And they knows that when they enter a city,they can destory all echantment generator in this city at once,and they can enter a city only if they has destoryed all enchantment generator for this city,but troops can stay at the outside of the city and can enter it at the moment its echantment is destoryed.Of course the U.S. army will face no resistance because the Mars keep no army,so troops can invade in many way at the same time.
Now the U.S. will invade the Mars,give you the map,your task is to calculate the minimium time to enter the capital of the Mars.

Input
The first line contains an integer T,which is the number of test cases.
For each testcase:
The first line contains two integers N and M,1<=N<=3000,1<=M<=70000,the cities is numbered from 1 to N and the U.S. landed on city 1 while the capital of the Mars is city N.
The next M lines describes M paths on the Mars.Each line contains three integers ai,bi and wi,indicates there is a unidirectional path form ai to bi lasts wi minutes(1<=wi<=10^8).
The next N lines describes N citys,the 1+M+i line starts with a integer li,followed with li integers, which is the number of cities has a echantment generator protects city i.
It's guaranteed that the city N will be always reachable.

Output
For each case,print a line with a number indicating the minimium time needed to enter the capital of the Mars.

Sample Input

1
6 6
1 2 1
1 4 3
2 3 1
2 5 2
4 6 2
5 3 2
0
0
0
1 3
0
2 3 5

Sample Output

5

Hint
The Map is like this:
We can follow these ways to achieve the fastest speed:
1->2->3,1->2->5,1->4->6.

Source
2011 Multi-University Training Contest 4 - Host by SDU

Recommend
lcy   |   We have carefully selected several similar problems for you:  3870 3869 3871 3878 3872


令pNum[i]=保护城市i的城市个数

pTime[i]=保护i的城市被攻破的最晚时间

toTime[i]=到达i城外的最短时间

dist[i]=攻破i的最短时间

当pNum=0时:dist[i]=max(pTime[i],toTime[i])

在Dijkstra中 不断更新toTime[v]

if(pNum==0)更新dist[v]

当u出队列时 显然dist[u]达到了最小值 此时更新u保护的v的pTime[v]

if(pNum[v]==0)将v加入队列

PS:当有k个点对u进行过松弛,u会入队k次,对u保护的v

pNum[v]显然只需要-1 所以需要标记u是否已经出过队列..(此处WA N次)

#include<iostream>
#include<stdlib.h>
#include<stdio.h>
#include<string>
#include<vector>
#include<deque>
#include<queue>
#include<algorithm>
#include<set>
#include<map>
#include<stack>
14ce3
#include<time.h>
#include<math.h>
#include<list>
#include<cstring>
#include<fstream>
//#include<memory.h>
using namespace std;
#define ll long long
#define ull unsigned long long
#define pii pair<int,int>
#define INF 1000000007
#define pll pair<ll,ll>
#define pid pair<int,double>

const ll inf=1e16;
const int N=3000+5;
const int M=70000+5;

struct Edge{//到达的城
int to,cost,next;
}edge[M];
int head
;

struct Protect{//保护的城
int v,next;
}edgeP[N*N];
int headP
;

inline void addEdge(int k,int u,int v,int c){
edge[k].to=v;
edge[k].cost=c;
edge[k].next=head[u];
head[u]=k;
}

inline void addEdgeP(int k,int u,int v){
edgeP[k].v=v;
edgeP[k].next=headP[u];
headP[u]=k;
}

ll dist
;//进入i的最短时间
ll toTime
;//到i城外的最短时间
ll pTime
;//保护i的城被攻破的最长时间
ll vis
;//标记是i否被pop过了 当有k个点对i进行过松弛操作,i会进入队列k次 显然 当i城被pop出队列 dist[i]已经是到达i的最短时间 update ptime[被i保护的城] 而--pNum[v]可能被执行k次
int pNum
;//pNum[i]=还在保护i城的城市数

void Dijkstra(int n){
fill(dist,dist+n+1,inf);
fill(toTime,toTime+n+1,inf);
fill(pTime,pTime+n+1,0);
fill(vis,vis+n+1, false);
priority_queue<pii,vector<pii>,greater<pii> >que;
dist[1]=0;
que.push({dist[1],1});
while(!que.empty()){
int u=que.top().second;
que.pop();
if(vis[u])
continue;
vis[u]=true;
for(int i=headP[u];i!=-1;i=edgeP[i].next){
int v=edgeP[i].v;
--pNum[v];
pTime[v]=max(pTime[v],dist[u]);
if(pNum[v]==0){
dist[v]=max(pTime[v],toTime[v]);
que.push({dist[v],v});
}
}
for(int i=head[u];i!=-1;i=edge[i].next){
int v=edge[i].to,c=edge[i].cost;
toTime[v]=min(toTime[v],dist[u]+c);
if(pNum[v]>0)
continue;
ll tmpTime=dist[v];
dist[v]=max(pTime[v],toTime[v]);
if(dist[v]<tmpTime){
que.push({dist[v],v});
}
}
}
}

int main()
{
freopen("/home/lu/文档/r.txt","r",stdin);
//freopen("/home/lu/文档/w.txt","w",stdout);
int n,m,T;
scanf("%d",&T);
while(T--){
scanf("%d%d",&n,&m);
fill(head,head+n+1,-1);
fill(headP,headP+n+1,-1);
fill(pNum,pNum+n+1,0);
for(int i=0,u,v,c;i<m;++i){
scanf("%d%d%d",&u,&v,&c);
addEdge(i,u,v,c);
}
for(int i=1,li,u,counter=0;i<=n;++i){
scanf("%d",&li);
pNum[i]=li;
while(li--){
scanf("%d",&u);
addEdgeP(counter++,u,i);
}
}
Dijkstra(n);
printf("%lld\n",dist
);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  HDU 图论 Dijkstra