对于 20%的数据,满足 N≤15,M≤50;
对于 50%的数据,满足 N≤500,M≤6,000;
对于 100%的数据,满足 N≤3,000,M≤70,000,1≤wi≤108
。
输入数据保证一定有解,且不会存在维持某个城市结界的结界发生器在这个
城市内部。
连接两个城市的道路可能不止一条, 也可能存在一个城市自己到自己的道路。
其实最畏惧图论题了QAQ写到这个题才发现自己的图论有多么弱
拿这个题练手了堆优化dijkstra
谢谢hzwer神犇的指导和模板支持
做法注释里写的很清楚了吧(大概)0-0
#include<iostream> #include<cstdio> #include<cstring> #include<cmath> #include<algorithm> #include<queue> #include<map> #define p pair<int,int> using namespace std; int n,m; int d1[3001],d2[3001],d[3001];//理论到达时间,实际进入时间,结界数目 bool flag[3001]; int top; int x,b,v; int num[3001]; int a[3001][3001];//记录结界保护关系 struct road { int to; road *next; int v; }s[70001],*prev[3001]; void insert(int a,int b,int v) { s[++top].to=b; s[top].next=prev[a]; s[top].v=v; prev[a]=&s[top]; } priority_queue<p,vector<p>,greater<p> >que; void dijkstra() { memset(d1,127/3,sizeof(d1)); que.push(make_pair(0,1)); d1[1]=0; while (!que.empty()) { int now=que.top().second; que.pop(); if (flag[now]) continue; flag[now]=1; int maxn=max(d1[now],d2[now]); road *x=prev[now]; while (x) { if (maxn+x->v<d1[x->to]) { d1[x->to]=maxn+x->v; int t=max(d1[x->to],d2[x->to]); if (!d[x->to]) que.push(make_pair(t,x->to)); } x=x->next; } for (int i=1;i<=num[now];i++) { int t=a[now][i]; d[t]--; d2[t]=max(d2[t],maxn); int tmp=max(d1[t],d2[t]); if (!d[t]) que.push(make_pair(tmp,t)); } } } int main() { //freopen("land.in","r",stdin); scanf("%d%d",&n,&m); for (int i=1;i<=m;i++) { scanf("%d%d%d",&x,&b,&v); if (x!=b) insert(x,b,v); } for (int i=1;i<=n;i++) { scanf("%d",&d[i]); for (int j=1;j<=d[i];j++) { scanf("%d",&x); a[x][++num[x]]=i; } } dijkstra(); printf("%d",max(d1[n],d2[n])); }
原文地址:http://blog.csdn.net/creationaugust/article/details/43082937