玛卡巴卡加强版求调,#10没过
查看原帖
玛卡巴卡加强版求调,#10没过
399475
_XHY20180718_楼主2024/1/16 20:37

WA on #10,assert 发现是在最短路上调大边权出锅了,而且输出的答案是最短路那边的。

(不一定是最短路挂了,也有可能是线段树qry的答案太大导致的)

RT,调出来扔个数据生成器或者HACK都行

#include<bits/stdc++.h>
#define int long long
#define x first
#define y second
#define mid (l+(r-l>>1))
#define ls (mid<<1)
#define rs (ls|1)
using namespace std;
const int N=2e5+5,M=2e5+5,INF=1e18+9;
int n,m,q,L,R,K,I,id;
int cnt[N],head[N],fa[N],ei;
map<pair<int,int>,bool>mp;
map<pair<int,int>,int>d;
map<pair<int,int>,int>sd;
struct Segment_Tree{
    int w=INF,fl=INF;
}tr[N<<1];
struct edge{
    int u,v,w,nxt;
}egs[M<<1];
int uu[M],vv[M],ww[M];
inline void add(int u,int v,int w)
{egs[++ei]={u,v,w,head[u]};head[u]=ei;}
inline void chgn(int id,int x)
{tr[id].w=min(tr[id].w,x),tr[id].fl=min(tr[id].fl,x);}
inline void pushdown(int l,int r,int id)
{int x=tr[id].fl;if(x!=INF)chgn(ls,x),chgn(rs,x);}
inline void upd(int l,int r,int id){
    if(L<=l&&r<=R){chgn(id,K);return;}
    pushdown(l,r,id);
    if(L<=mid)upd(l,mid,ls);
    if(mid<R)upd(mid+1,r,rs);
    tr[id].w=max(tr[ls].w,tr[rs].w);
}
inline int qry(int l,int r,int id){
    if(l==r)return tr[id].w;pushdown(l,r,id);
    return (mid<I?qry(l,mid,ls):qry(mid+1,r,rs));
}
struct Dijkstra{
    struct node{
        int u,w;
        bool operator<(const node &t)
        const{return w>t.w;}
    };
    priority_queue<node>qu;
    int dis[N],lst[N];
    bool vis[N];
    inline void solve(int s){
        for(int i=1; i<=n; ++i)dis[i]=INF;
        qu.push({s,0});dis[s]=0;
        while(!qu.empty()){
            int u=qu.top().u;qu.pop();
            if(vis[u])continue;vis[u]=1;
            for(int i=head[u];i;i=egs[i].nxt){
                const int v=egs[i].v,w=egs[i].w;
                if(dis[v]>dis[u]+w){
                    dis[v]=dis[u]+w,lst[v]=u;
                    qu.push({v,dis[v]});
                }
            }
        }
    }
}S,T;
inline int find(int x){
    while(x!=fa[x])
        x=fa[x]=fa[fa[x]];
    return x;
}
signed main(){
	// freopen("test.in","r",stdin);
	// freopen("test.out","w",stdout);
    ios::sync_with_stdio(0);
    cin.tie(0),cout.tie(0);
    cin>>n>>m>>q;int u,v,w;
    for(int i=1; i<=m; ++i){
        cin>>u>>v>>w;uu[i]=u,vv[i]=v,ww[i]=w;
        if(!d[{u,v}])d[{u,v}]=d[{v,u}]=w;
        else {
            if(d[{u,v}]>w)sd[{u,v}]=sd[{v,u}]=d[{u,v}],d[{u,v}]=d[{v,u}]=w;
            else if(!sd[{u,v}])sd[{u,v}]=sd[{v,u}]=w;
            else sd[{u,v}]=sd[{v,u}]=min(sd[{u,v}],w);
        }
    }
    for(auto eg:d)add(eg.x.x,eg.x.y,eg.y);
    S.solve(1),T.solve(n);
    for(int u=1; u<=n; ++u)fa[u]=T.lst[u]?T.lst[u]:u;
    for(int u=1; u!=n; u=T.lst[u]){
        cnt[u]=++id;fa[u]=u;mp[{u,T.lst[u]}]=1;
    }cnt[n]=id+1;
    for(auto eg:d){
        u=eg.x.x,v=eg.x.y,w=eg.y;
        if(u>v)continue;
        if(mp[{u,v}]||mp[{v,u}])continue;
        L=cnt[find(u)],R=cnt[find(v)];
        if(!L||!R)continue;
        if(L==R)continue;if(L>R)swap(L,R);--R;
        K=min(S.dis[u]+T.dis[v],S.dis[v]+T.dis[u])+w;
        upd(1,id,1);
    }int t,x,res;
    while(q--){
        res=S.dis[n],cin>>t>>x;
        u=uu[t],v=vv[t],w=ww[t];
        if(x<w)res=min(min(T.dis[u]+S.dis[v],T.dis[v]+S.dis[u])+x,res);
        if(d[{u,v}]==w){
            if(x>w){if(sd[{u,v}])x=min(x,sd[{u,v}]);
                if(mp[{u,v}]||mp[{v,u}])
                I=min(cnt[u],cnt[v]),res=min(qry(1,id,1),min(T.dis[u]+S.dis[v],T.dis[v]+S.dis[u])+x);
            }
        }
        cout<<res<<'\n';
    }
    return 0;
}
2024/1/16 20:37
加载中...