BZOJ1922大陆争霸

思路:带限制的单源最短路

限制每个点的条件有二,路程和最早能进入的时间,那么对两个值一起限制跑最短路,显然想要访问一个点最少满足max(dis,time)

那么每次把相连的点以及所保护的点扔进堆中,用以更新答案,不过值得注意的是,入堆的时候进行判断

Code:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
using namespace std;
#define p pair<int,int>
int read()
{
    int x=0,f=1; char ch=getchar();
    while (ch<'0' || ch>'9') {if (ch=='-') f=-1; ch=getchar();}
    while (ch>='0' && ch<='9') {x=x*10+ch-'0'; ch=getchar();}
    return x*f;
}
#define maxn 3010
#define maxm 70010
int n,m;
struct data{int to,next,w;}edge[maxm];
int l[maxn][maxn],lt[maxn],ll[maxn];
int head[maxn],cnt;
int S,T;

void add(int u,int v,int w)
{
    cnt++;
    edge[cnt].next=head[u];  head[u]=cnt;
    edge[cnt].to=v; edge[cnt].w=w;
}

int dis1[maxn],dis2[maxn];
bool visit[maxn];
priority_queue<p,vector<p>,greater<p> >q;
void dijkstra()
{
    memset(dis1,0x3f,sizeof(dis1));
    q.push(make_pair(0,S));  dis1[S]=0;
    while (!q.empty())
        {
            int now=q.top().second; q.pop(); 
            if(visit[now]) continue; visit[now]=1;
            //printf("%d\n",now);
            int dis=max(dis1[now],dis2[now]);
            for (int i=head[now]; i; i=edge[i].next)    
                if (dis+edge[i].w<dis1[edge[i].to])
                    {
                        dis1[edge[i].to]=dis+edge[i].w;
                        int tmp=max(dis1[edge[i].to],dis2[edge[i].to]);
                        if(!ll[edge[i].to]) q.push(make_pair(tmp,edge[i].to));
                    }
            //printf("%d\n",lt[now]);
            for (int i=1; i<=lt[now]; i++)
                {
                    int noww=l[now][i]; ll[noww]--;
                    dis2[noww]=max(dis2[noww],dis);
                    if (!ll[noww]) q.push(make_pair(max(dis1[noww],dis2[noww]),noww));
                }
        }
}

int main()
{
    n=read(),m=read();
    for (int i=1; i<=m; i++)
        {
            int u=read(),v=read(),w=read();
            if (u!=v) add(u,v,w);
        }
    for (int i=1; i<=n; i++)
        {
            ll[i]=read();
            for (int j=1; j<=ll[i]; j++)
                {
                    int x=read();
                    l[x][++lt[x]]=i;
                }
        }
    S=1;T=n;
    dijkstra();
//  for (int i=1; i<=n; i++)
//      printf("%d %d\n",dis1[i],dis2[i]);
    printf("%d\n",max(dis1[T],dis2[T]));
    return 0;
}
大陆争霸

相关文章:

  • 2022-12-23
  • 2021-10-01
  • 2021-09-30
  • 2021-08-23
  • 2022-12-23
  • 2022-02-18
  • 2021-06-22
  • 2021-06-25
猜你喜欢
  • 2021-11-23
  • 2021-08-07
  • 2022-01-20
  • 2021-06-21
  • 2021-12-12
  • 2021-06-25
  • 2021-09-06
相关资源
相似解决方案