社区讨论
第一个hackRE了求调
P2685[TJOI2012] 桥参与者 3已保存回复 4
讨论操作
快速查看讨论及其快照的属性,并进行相关操作。
- 当前回复
- 4 条
- 当前快照
- 1 份
- 快照标识符
- @mcbrclxi
- 此快照首次捕获于
- 2025/06/25 17:34 8 个月前
- 此快照最后确认于
- 2025/11/04 06:58 4 个月前
CPP
/*
Luogu name: Symbolize
Luogu uid: 672793
*/
#include<bits/stdc++.h>
#define int long long
#define pii pair<int,int>
#define x first
#define y second
#define rep1(i,l,r) for(register int i=l;i<=r;++i)
#define rep2(i,l,r) for(register int i=l;i>=r;--i)
#define rep3(i,x,y,z) for(register int i=x[y];~i;i=z[i])
#define rep4(i,x) for(auto i:x)
#define debug() puts("----------")
const int N=2e6+10;
const int inf=0x3f3f3f3f3f3f3f3f;
using namespace std;
int n,m,h[N],e[N],ne[N],w[N],id[N],idx,dist[2][N],rdl[N],rdr[N],cnt[N],kase;
bool vis[N];
struct Graph
{
int u,v;
int w;
}G[N];
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<<1)+(x<<3)+(ch^48);
ch=getchar();
}
return f*x;
}
void add(int x,int y,int z,int d)
{
e[idx]=y;
w[idx]=z;
ne[idx]=h[x];
id[idx]=d;
h[x]=idx++;
return;
}
void dijkstra(int s,int d)
{
memset(vis,0,sizeof vis);
memset(dist[d],inf,sizeof dist[d]);
dist[d][s]=0;
priority_queue<pii> q;
q.push(make_pair(0,s));
while(!q.empty())
{
int x=q.top().y;
q.pop();
if(vis[x]) continue;
vis[x]=1;
rep3(i,h,x,ne)
{
int to=e[i];
if(dist[d][to]>dist[d][x]+w[i])
{
dist[d][to]=dist[d][x]+w[i];
q.push(make_pair(-dist[d][to],to));
}
}
}
return;
}
void dfs0()
{
memset(vis,0,sizeof vis);
queue<int> q;
q.push(1);
vis[1]=1;
while(!q.empty())
{
int t=q.front();
q.pop();
rep3(i,h,t,ne)
{
int to=e[i];
if(dist[0][to]==dist[0][t]+w[i]&&!vis[to])
{
if(!rdl[to]) rdl[to]=rdl[t];
vis[to]=1;
q.push(to);
}
}
}
return;
}
void dfs1()
{
memset(vis,0,sizeof vis);
queue<int> q;
q.push(n);
while(!q.empty())
{
int t=q.front();
q.pop();
rep3(i,h,t,ne)
{
int to=e[i];
if(dist[1][to]==dist[1][t]+w[i]&&!vis[to])
{
if(!rdr[to])
{
rdr[to]=rdr[t];
// cout<<to<<' '<<t<<' '<<rdr[t]<<"\n";
}
vis[to]=1;
q.push(to);
}
}
}
return;
}
struct Segment_Tree
{
struct node
{
int l,r;
int Min;
int tag;
}tr[N<<2];
int ls(int p){return p<<1;}
int rs(int p){return p<<1|1;}
void push_up(int p){tr[p].Min=min(tr[ls(p)].Min,tr[rs(p)].Min);}
void build(int p,int l,int r)
{
tr[p]={l,r,inf,inf};
if(l==r) return;
int mid=l+r>>1;
build(ls(p),l,mid);
build(rs(p),mid+1,r);
push_up(p);
return;
}
void push_down(int p)
{
tr[ls(p)].Min=min(tr[ls(p)].Min,tr[p].tag);
tr[rs(p)].Min=min(tr[rs(p)].Min,tr[p].tag);
tr[ls(p)].tag=min(tr[ls(p)].tag,tr[p].tag);
tr[rs(p)].tag=min(tr[rs(p)].tag,tr[p].tag);
tr[p].tag=inf;
return;
}
void update(int p,int l,int r,int k)
{
if(tr[p].l>=l&&tr[p].r<=r)
{
tr[p].Min=min(tr[p].Min,k);
tr[p].tag=min(tr[p].tag,k);
return;
}
push_down(p);
int mid=tr[p].l+tr[p].r>>1;
if(l<=mid) update(ls(p),l,r,k);
if(r>mid) update(rs(p),l,r,k);
push_up(p);
return;
}
int query(int p,int x)
{
if(tr[p].l==tr[p].r) return tr[p].Min;
push_down(p);
int mid=tr[p].l+tr[p].r>>1;
if(x<=mid) return query(ls(p),x);
else return query(rs(p),x);
}
}seg;
signed main()
{
// freopen("data.in","r",stdin);
// freopen(".out","w",stdout);
memset(h,-1,sizeof h);
n=read();
m=read();
rep1(i,1,m)
{
G[i*2-1].u=G[i*2].v=read();
G[i*2-1].v=G[i*2].u=read();
G[i*2-1].w=G[i*2].w=read();
add(G[i*2-1].u,G[i*2-1].v,G[i*2-1].w,i*2-1);
add(G[i*2].u,G[i*2].v,G[i*2].w,i*2);
}
// debug();
dijkstra(1,0);
dijkstra(n,1);
// cout<<dist[0][n]<<"\n";
if(dist[0][n]>=inf) return 0;
rdl[1]=rdr[1]=-1;
cnt[0]=0;
int now=1;
while(now!=n)
{
rep3(i,h,now,ne)
{
int to=e[i];
if(dist[1][now]==dist[1][to]+w[i])
{
rdl[to]=rdr[to]=id[i];
cnt[id[i]]=++kase;
now=to;
break;
}
}
}
dfs0();
dfs1();
rep1(i,1,n)
{
if(rdl[i]==-1) rdl[i]=0;
if(rdr[i]==-1) rdr[i]=0;
// cout<<G[rdr[i]].u<<' '<<G[rdr[i]].v<<"\n";
}
// putchar('\n');
seg.build(1,1,kase);
rep1(i,1,2*m)
{
if(rdl[G[i].v]==i) continue;
int L=cnt[rdl[G[i].u]]+1,R=cnt[rdr[G[i].v]];
if(L>R) continue;
// cout<<G[i].u<<' '<<G[i].v<<' '<<G[i].w<<"\n";
int dis=dist[0][G[i].u]+G[i].w+dist[1][G[i].v];
// cout<<G[i].u<<' '<<G[i].v<<' '<<dis<<' '<<L<<' '<<R<<"\n";
// cout<<G[i].w<<"\n";
seg.update(1,L,R,dis);
}
int Min=-inf,cnt=0;
rep1(i,1,kase)
{
int dis=seg.query(1,i);
if(Min<dis)
{
Min=dis;
cnt=1;
}
else if(Min==dis) ++cnt;
}
cout<<Min<<' ';
if(Min==dist[0][n]) cout<<m<<"\n";
else cout<<cnt<<"\n";
return 0;
}
/*
15 30
3 7 46
3 10 21
1 2 6
6 9 34
2 11 34
3 5 49
14 7 36
6 15 31
15 10 21
1 2 35
8 6 39
15 15 12
7 7 26
9 4 39
8 15 32
15 7 4
8 8 6
13 14 12
3 7 7
10 3 26
6 3 24
6 1 50
7 5 25
4 11 21
4 15 37
1 3 9
3 7 17
2 15 41
2 10 15
9 11 29
*/
回复
共 4 条回复,欢迎继续交流。
正在加载回复...