CodeForces - 1484F Useful Edges(最短路)
題目鏈接:點擊查看
題目大意:給出由 nnn 個點構成的無向圖,再給出 qqq 個三元對 (u,v,l)(u,v,l)(u,v,l),現在問有多少條邊 (i,j)(i,j)(i,j) 可以和至少一個三元對匹配,可以匹配的條件是:
從點 uuu 到點 vvv 且包含邊 (i,j)(i,j)(i,j) 的最短路的長度需要小于等于 lll
題目分析:題目本身不難,就是有點繞,先考慮一下暴力思路
可以先 O(m)O(m)O(m) 去枚舉每條邊,然后再 O(q)O(q)O(q) 去枚舉每個詢問,設 di,jd_{i,j}di,j? 是點 iii 到點 jjj 的最短路,如果滿足 du,i+wi,j+dj,v<=ld_{u,i}+w_{i,j}+d_{j,v}<=ldu,i?+wi,j?+dj,v?<=l 則當前的邊可以記錄貢獻
不過上述暴力的時間復雜度是 O(n4)O(n^4)O(n4) 的,考慮對公式進行移項
du,i+wi,j+dj,v<=ld_{u,i}+w_{i,j}+d_{j,v}<=ldu,i?+wi,j?+dj,v?<=l 變成 dj,v+wi,j<=l?du,id_{j,v}+w_{i,j}<=l-d_{u,i}dj,v?+wi,j?<=l?du,i?
這樣一來我們就可以將不等式右邊視為一個整體,不難發現當固定了 iii 后,不等式左右兩側就可以分別計算,這樣時間復雜度就降下來了
具體就是,在固定 iii 后,維護 mmaxummax_ummaxu? 為相應 l?du,il-d_{u,i}l?du,i? 的最大值
然后枚舉 jjj 以及 uuu 就可以計算貢獻了
代碼:
// Problem: F. Useful Edges // Contest: Codeforces - Codeforces Round #709 (Div. 2, based on Technocup 2021 Final Round) // URL: https://codeforces.com/contest/1484/problem/F // Memory Limit: 512 MB // Time Limit: 5000 ms // // Powered by CP Editor (https://cpeditor.org)// #pragma GCC optimize(2) // #pragma GCC optimize("Ofast","inline","-ffast-math") // #pragma GCC target("avx,sse2,sse3,sse4,mmx") #include<iostream> #include<cstdio> #include<string> #include<ctime> #include<cmath> #include<cstring> #include<algorithm> #include<stack> #include<climits> #include<queue> #include<map> #include<set> #include<sstream> #include<cassert> #include<bitset> #define lowbit(x) x&-x using namespace std; typedef long long LL; typedef unsigned long long ull; template<typename T> inline void read(T &x) {T f=1;x=0;char ch=getchar();while(0==isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}while(0!=isdigit(ch)) x=(x<<1)+(x<<3)+ch-'0',ch=getchar();x*=f; } template<typename T> inline void write(T x) {if(x<0){x=~(x-1);putchar('-');}if(x>9)write(x/10);putchar(x%10+'0'); } const int inf=0x3f3f3f3f; const int N=610; LL d[N][N],w[N][N],mmax[N]; vector<pair<int,int>>node[N]; int main() { #ifndef ONLINE_JUDGE // freopen("data.in.txt","r",stdin); // freopen("data.out.txt","w",stdout); #endif // ios::sync_with_stdio(false);int n,m;read(n),read(m);for(int i=1;i<=n;i++) {for(int j=1;j<=n;j++) {d[i][j]=i==j?0:1e18;w[i][j]=0;}}while(m--) {int u,v,val;read(u),read(v),read(val);w[u][v]=w[v][u]=val;d[u][v]=d[v][u]=val;}int q;read(q);while(q--) {int u,v,w;read(u),read(v),read(w);node[u].push_back({v,w});node[v].push_back({u,w});}for(int k=1;k<=n;k++) {for(int i=1;i<=n;i++) {for(int j=1;j<=n;j++) {d[i][j]=min(d[i][j],d[i][k]+d[k][j]);}}}int ans=0;for(int i=1;i<=n;i++) {memset(mmax,0,sizeof(LL)*(n+5));for(int u=1;u<=n;u++) {for(auto it:node[u]) {int v,l;tie(v,l)=it;mmax[u]=max(mmax[u],l-d[v][i]);}}for(int j=i+1;j<=n;j++) {if(w[i][j]==0) {continue;}for(int k=1;k<=n;k++) {if(w[i][j]+d[j][k]<=mmax[k]) {ans++;break;}}}}cout<<ans<<endl;return 0; }總結
以上是生活随笔為你收集整理的CodeForces - 1484F Useful Edges(最短路)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: CodeForces - 1529F I
- 下一篇: CodeForces - 1497D G