P4568 [JLOI2011]飞行路线——(分层图最短路)

总结

把每个图分成k+1层,然后每层之间:i到i+1层的建立单向边,权值为0,然后跑dijkstra,枚举0到k次免费的ans,取最小。

自己的问题

已经两次写dijkstra忘记判断如果u点访问,跳出当前循环,然后TLE了N次才发现

题目链接

//#pragma GCC optimize(2)
#include
//typedef long long ll;
#define ull       unsigned long long
//#define int       long long
#define F           first
#define S           second
#define endl        "\n"//<
#define eps         1e-6
#define base        131
#define lowbit(x)   (x&(-x))
#define PI          acos(-1.0)
#define inf         0x3f3f3f3f
#define MAXN        0x7fffffff
#define INF         0x3f3f3f3f3f3f3f3f
#define ferma(a,b)  pow(a,b-2)
#define pb          push_back
#define all(x)      x.begin(),x.end()
#define memset(a,b) memset(a,b,sizeof(a));
#define IOS         ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
using namespace std;
void file()
{
#ifdef ONLINE_JUDGE
#else
    freopen("D:/LSNU/codeforces/duipai/data.txt","r",stdin);
    //  freopen("D:/LSNU/codeforces/duipai/WA.txt","w",stdout);
#endif
}
const int N=3e5+5;
const int M=3e6+5;
struct node
{
    int u,dis,next;
}ss[M];
int dis[N],vis[N];
int head[N],pos=0;
void add(int u,int v,int dis)
{
    ss[++pos]=(node){v,dis,head[u]};
    head[u]=pos;
}
void dijkstra(int s)
{
    memset(dis,inf);
    dis[s]=0;
    priority_queue<pair<int,int> >pri;
    pri.push({0,s});
    while(!pri.empty())
    {
        pair<int,int> u=pri.top();
        pri.pop();
        if(vis[u.S])
            continue;
        vis[u.S]=true;
        for(int i=head[u.S];i;i=ss[i].next)
        {
            if(vis[ss[i].u]||dis[u.S]+ss[i].dis>dis[ss[i].u])
                continue;
            dis[ss[i].u]=dis[u.S]+ss[i].dis;
            pri.push({-dis[ss[i].u],ss[i].u});
        }
    }
}
signed main()
{
    IOS;
    // file();
    int n,m,k;
    scanf("%d%d%d",&n,&m,&k);
    int s,t;
    scanf("%d%d",&s,&t);
    for(int i=0;i<m;i++)
    {
        int u,v,dis;
        scanf("%d%d%d",&u,&v,&dis);
        add(u,v,dis);
        add(v,u,dis);
        for(int j=1;j<=k;j++)
        {
            add(u+(j-1)*n,v+j*n,0);
            add(v+(j-1)*n,u+j*n,0);
            add(u+j*n,v+j*n,dis);
            add(v+j*n,u+j*n,dis);
        }
    }
    dijkstra(s);
    int ans=inf;
    for(int i=0;i<=k;i++)
        ans=min(ans,dis[t+i*n]);
    printf("%d\n",(ans==inf?-1:ans));
    return 0;
}

你可能感兴趣的:(#,最短路)