3 条题解
-
1
提供一种我不会证正确性的做法既然要使最短路的长度刚好加一,那被加的这条边要刚好使所有的最短路径都经过它。
于是跑一遍最短路,求由最短路径构成的图的所有割边。
在所有最短路的长度被增加后,还要有路径长度为最短路加一的路径存在,不然实际上操作后最短路的长度就会被加上二。
正着反着跑一遍最短路,遍历所有边,若两端点到起点终点的最短路加上这条边的长度刚好为最短路的长度加一,就说明存在。
考虑到若被加的一条边会影响所有的最短路长度加一的路径,那么这条边就不能加。
于是再用最短路长度加一的路径建一张图,继续求割边。
最终答案就是所有最短路的割边且不是最短路长度加一的路径的割边的边。
码:
#include<bits/stdc++.h> using namespace std; #define int long long const int MaxN=300000; int n,m; vector<tuple<int,int,int> >g[MaxN+1],t[MaxN+1],s[MaxN+1]; tuple<int,int,int>edge[MaxN+1]; struct Tarjan{ vector<int>dfn,low; vector<bool>bridge; int sign; Tarjan(){} Tarjan(int n,int m,const vector<tuple<int,int,int> >*g){ dfn=vector<int>(n+1,0); low=vector<int>(n+1,0); bridge=vector<bool>(m+1,0); sign=0; Dfs(1,0,g); } void Dfs(int u,int prt,const vector<tuple<int,int,int> >*g){ dfn[u]=low[u]=++sign; for(auto&tup:g[u]){ int v,id; tie(v,ignore,id)=tup; if(v==prt)continue; if(!dfn[v]){ Dfs(v,u,g); low[u]=min(low[u],low[v]); if(dfn[u]<low[v])bridge[id]=true; }else low[u]=min(low[u],dfn[v]); } } }tt,st; struct HeapNode{ HeapNode(){} HeapNode(int u,int val):u(u),val(val){} int u,val; bool operator<(const HeapNode&obj)const{return val>obj.val;} }; int dis1[MaxN+1],dis2[MaxN+1]; bool vst[MaxN+1]; vector<pair<int,int> >par1[MaxN+1],par2[MaxN+1]; void Dijkstra(int st,int*dis,vector<pair<int,int> >*par){ priority_queue<HeapNode>q; for(int i=1;i<=n;i++){ dis[i]=LLONG_MAX; vst[i]=false; par[i].clear(); } dis[st]=0; q.emplace(st,0); while(!q.empty()){ int u=q.top().u;q.pop(); if(vst[u])continue; vst[u]=true; for(auto&tup:g[u]){ int v,d,id; tie(v,d,id)=tup; if(dis[u]+d<dis[v]){ dis[v]=dis[u]+d; par[v]={{u,id}}; q.emplace(v,dis[v]); }else if(dis[u]+d==dis[v]) par[v].emplace_back(u,id); } } } void Dfs(int u){ for(auto&pi:par1[u]){ int prt=pi.first,id=pi.second; Dfs(prt); t[prt].emplace_back(u,0,id); t[u].emplace_back(prt,0,id); } } bool tag[MaxN+1]; void Dfs2(int u){ if(tag[u])return; tag[u]=true; for(auto&pi:par1[u]){ int prt=pi.first,id=pi.second; Dfs2(prt); s[prt].emplace_back(u,0,id); s[u].emplace_back(prt,0,id); } } void Dfs3(int u){ if(tag[u])return; tag[u]=true; for(auto&pi:par2[u]){ int prt=pi.first,id=pi.second; Dfs3(prt); s[prt].emplace_back(u,0,id); s[u].emplace_back(prt,0,id); } } void Solve(){ cin>>n>>m; for(int i=1;i<=n;i++) g[i].clear(), t[i].clear(), s[i].clear(), par1[i].clear(), par2[i].clear(), tag[i]=false; for(int i=1;i<=m;i++){ int u,v,w; cin>>u>>v>>w; g[u].emplace_back(v,w,i); g[v].emplace_back(u,w,i); edge[i]=make_tuple(u,v,w); } Dijkstra(1,dis1,par1); Dfs(n); int stt=dis1[n]; Dijkstra(n,dis2,par2); int flag=0; for(int i=1;i<=m;i++){ int u,v,w; tie(u,v,w)=edge[i]; if(dis1[u]+dis2[v]+w==stt+1){ ++flag; s[u].emplace_back(v,0,i); s[v].emplace_back(u,0,i); Dfs2(u); Dfs3(v); } swap(u,v); if(dis1[u]+dis2[v]+w==stt+1){ ++flag; s[u].emplace_back(v,0,i); s[v].emplace_back(u,0,i); Dfs2(u); Dfs3(v); } } for(int u=1;u<=n;u++){ sort(s[u].begin(),s[u].end()); s[u].resize(unique(s[u].begin(),s[u].end())-s[u].begin()); } tt=Tarjan(n,m,t); st=Tarjan(n,m,s); if(!flag){ cout<<"0\n\n"; return; }else{ vector<int>ans; for(int i=1;i<=m;i++) if(tt.bridge[i]&&!st.bridge[i]) ans.push_back(i); cout<<ans.size()<<'\n'; for(int val:ans)cout<<val<<' '; cout<<'\n'; } } #undef int int main(){ ios::sync_with_stdio(false); cin.tie(0); int T; cin>>T; while(T--) Solve(); return 0; } -
0
#include<bits/stdc++.h> using namespace std; typedef long long ll; int n,m,t; struct N{ ll y,v,id; bool operator<(const N &n1)const{ return v>n1.v; } }; struct Edge{ ll x,y,v; }E[300010]; vector<N> e[300010]; ll d1[300010],d2[300010]; int vis[300010]; struct N2{ int y,id; }; vector<N2> e2[300010],pre1[300010],pren[300010]; void dijkstra(int x,ll dis[],vector<N2> pre[]){ priority_queue<N> q; q.push({x,0}); for(int i=1;i<=n;i++){ dis[i]=1e18;vis[i]=0; } dis[x]=0; while(!q.empty()){ N t=q.top(); q.pop(); if(vis[t.y])continue; vis[t.y]=1; for(N i:e[t.y]){ if(dis[i.y]>dis[t.y]+i.v){ dis[i.y]=dis[t.y]+i.v; q.push({i.y,dis[i.y]}); pre[i.y]={{t.y,i.id}}; } else if(dis[i.y]==dis[t.y]+i.v){ pre[i.y].push_back({t.y,i.id}); } } } } int dfn[300010],low[300010],tsp,brg[300010],v2[300010]; void tarjan(int x,int yid){ dfn[x]=low[x]=++tsp; for(N2 i:e2[x])if(i.id!=yid){ if(dfn[i.y]==0){ tarjan(i.y,i.id); low[x]=min(low[x],low[i.y]); if(dfn[x]<low[i.y])brg[i.id]=1; } else{ low[x]=min(low[x],dfn[i.y]); } } } void dfs1(int x){ if(v2[x])return ; v2[x]=1; for(N2 i:pre1[x]){ dfs1(i.y); e2[x].push_back({i.y,i.id}); e2[i.y].push_back({x,i.id}); } } void dfsn(int x){ if(v2[x])return ; v2[x]=1; for(N2 i:pren[x]){ dfsn(i.y); e2[x].push_back({i.y,i.id}); e2[i.y].push_back({x,i.id}); } } int main(){ ios::sync_with_stdio(0); cin.tie(0); cin>>t; while(t--){ cin>>n>>m; for(int i=1;i<=n;i++)e[i].clear(),pre1[i].clear(),pren[i].clear(); for(int i=1,x,y,v;i<=m;i++){ cin>>x>>y>>v; e[x].push_back({y,v,i}); e[y].push_back({x,v,i}); E[i]={x,y,v}; } dijkstra(1,d1,pre1); dijkstra(n,d2,pren); ll len=d1[n]; for(int i=1;i<=n;i++)e2[i].clear(); for(int i=1;i<=m;i++){ int x=E[i].x,y=E[i].y,v=E[i].v; if(d1[x]+v+d2[y]==len){ e2[x].push_back({y,i}); e2[y].push_back({x,i}); } if(d1[y]+v+d2[x]==len){ e2[x].push_back({y,i}); e2[y].push_back({x,i}); } } for(int i=1;i<=n;i++)dfn[i]=low[i]=0; for(int i=1;i<=m;i++)brg[i]=0; tarjan(1,0); for(int i=1;i<=n;i++)v2[i]=0,e2[i].clear(),dfn[i]=low[i]=0; for(int i=1;i<=m;i++)vis[i]=brg[i],brg[i]=0; int fl=0; for(int i=1;i<=m;i++){ int x=E[i].x,y=E[i].y,v=E[i].v; if(d1[x]+v+d2[y]==len+1){ e2[x].push_back({y,i}); e2[y].push_back({x,i}); dfs1(x); dfsn(y); fl=1; } if(d1[y]+v+d2[x]==len+1){ e2[x].push_back({y,i}); e2[y].push_back({x,i}); dfs1(y); dfsn(x); fl=1; } } if(!fl){ cout<<"0\n\n"; continue; } tarjan(1,0); vector<int> ans; for(int i=1;i<=m;i++){ if(vis[i]&&!brg[i])ans.push_back(i); } cout<<ans.size()<<'\n'; for(int i:ans){ cout<<i<<" "; } cout<<'\n'; } return 0; } -
0
多测记得清空
#include<bits/stdc++.h> using namespace std; #define int long long #define PII pair<int,int> #define fi first #define se second const int N=3e5+10,inf=1e18; vector<PII>G[N],G2[N]; struct node{int x,y,c;}e[N]; int n,m,d[N],v[N],a[N],b[N],vv[N];map<PII,int>mp; vector<int>pre[N],pre1[N]; void dij1(int st) { priority_queue<PII,vector<PII>,greater<PII>>q; for(int i=1;i<=n;i++)d[i]=inf,v[i]=0; d[st]=0;q.push({0,st}); while(!q.empty()) { int x=q.top().se;q.pop(); if(v[x])continue;v[x]=1; for(auto i:G[x]) { int y=i.fi,w=i.se; if(d[y]>d[x]+w) { d[y]=d[x]+w; pre[y].clear();pre[y].push_back(x); q.push({d[y],y}); } else if(d[y]==d[x]+w)pre[y].push_back(x); } } } void dij2(int st) { priority_queue<PII,vector<PII>,greater<PII>>q; for(int i=1;i<=n;i++)d[i]=inf,v[i]=0; d[st]=0;q.push({0,st}); while(!q.empty()) { int x=q.top().se;q.pop(); if(v[x])continue;v[x]=1; for(auto i:G[x]) { int y=i.fi,w=i.se; if(d[y]>d[x]+w) { d[y]=d[x]+w; pre1[y].clear();pre1[y].push_back(x); q.push({d[y],y}); } else if(d[y]==d[x]+w)pre1[y].push_back(x); } } } int dfn[N],low[N],cut[N],tsp,cnt; void tarjan(int x,int f,int k) { dfn[x]=low[x]=++tsp; for(auto i:G2[x])if(i.se!=f) { int y=i.fi,id=i.se; if(dfn[y]==0) { tarjan(y,id,k); low[x]=min(low[x],low[y]); if(low[y]>dfn[x])cut[id]=k; } else low[x]=min(low[x],dfn[y]); } } int v1[N],v2[N],vvv[N]; void make(int x) { if(v1[x])return;v1[x]=1; for(int y:pre[x]) { make(y); int id=mp[{x,y}]; if(vvv[id])continue;vvv[id]=1; G2[x].push_back({y,id}); G2[y].push_back({x,id}); } } void make1(int x) { if(v2[x])return;v2[x]=1; for(int y:pre1[x]) { make1(y); int id=mp[{x,y}]; if(vvv[id])continue;vvv[id]=1; G2[x].push_back({y,id}); G2[y].push_back({x,id}); } } void solve() { cin>>n>>m; for(int i=1;i<=n;i++) G[i].clear(),G2[i].clear(),pre[i].clear(),pre1[i].clear(); for(int i=1;i<=m;i++) vv[i]=cut[i]=v1[i]=v2[i]=vvv[i]=0; tsp=cnt=0,mp.clear(); for(int i=1;i<=m;i++) { int x,y,c;cin>>x>>y>>c;e[i]={x,y,c}; G[x].push_back({y,c}); G[y].push_back({x,c}); mp[{x,y}]=mp[{y,x}]=i; } dij1(1);for(int i=1;i<=n;i++)a[i]=d[i]; int len=d[n]; dij2(n);for(int i=1;i<=n;i++)b[i]=d[i]; deque<int>q;q.push_back(n); while(!q.empty()) { int x=q.front();q.pop_front(); for(int y:pre[x]) { int id=mp[{x,y}]; G2[x].push_back({y,id}); G2[y].push_back({x,id}); if(!vv[y])vv[y]=1,q.push_back(y); } } for(int i=1;i<=n;i++)dfn[i]=low[i]=0; tarjan(1,0,1); for(int i=1;i<=n;i++)dfn[i]=low[i]=0,G2[i].clear(); bool bk=0; for(int i=1;i<=m;i++) { int x=e[i].x,y=e[i].y,w=e[i].c; if(a[x]+b[y]+w==len+1) { bk=1; make(x);make1(y); int id=mp[{x,y}]; if(vvv[id])continue;vvv[id]=1; G2[x].push_back({y,id}); G2[y].push_back({x,id}); } if(a[y]+b[x]+w==len+1) { bk=1; make(y);make1(x); int id=mp[{x,y}]; if(vvv[id])continue;vvv[id]=1; G2[x].push_back({y,id}); G2[y].push_back({x,id}); } } if(!bk) { cout<<0<<"\n\n"; return ; } tarjan(1,0,0); vector<int>ans; for(int i=1;i<=m;i++)if(cut[i])ans.push_back(i); cout<<ans.size()<<'\n'; for(int y:ans)cout<<y<<' ';cout<<'\n'; } signed main() { int t;cin>>t; while(t--)solve(); return 0; }
- 1
信息
- ID
- 7437
- 时间
- 4000ms
- 内存
- 512MiB
- 难度
- 9
- 标签
- 递交数
- 15
- 已通过
- 3
- 上传者