Educational Codeforces Round 102 (Rated for Div. 2) E
E. Minimum Path
题意 : 给你一个无向加权图,对于一条路径(不一定是简单路径,比如对于图1−2−3,1−>2−>3−>2这种有些边走了2次的就不是简单路径),他的路径总权值为路径上每一条经过边的和减去路径上最大的边权加上路径上最小的边权。让你求1点到每个点的最小满足上述条件的路径权值。
思路 :分层图。
由于不知道从1到某一点的路径究竟是怎么样的(不知道经过哪些点,不知道最大最小值,不知道是否为简单路径。。。)。但这条路径中只有一个最大值和一个最小值,对于某一条边我们可以得到4个状态:

①这条边即不是最大值也不是最小值。
②这条边是最大值
③这条边是最小值
④这条边即是最大值也是最小值
满足公式即可
#include <bits/stdc++.h>
#define int long long
#define x first
#define y second
#define PII pair<int,int>
#define LL long long
#define pb push_back
#define pqp priority_queue<PII,vector<PII>,greater<PII>>
#define pqi priority_queue<int,vector<int>,greater<int>>
#define PSS pair<string,string>
#define in insert
#define line inline
#define sort(s) sort(s.begin(),s.end());
#define V vector<int>
#define VV vector<V>
#define IOS ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
using namespace std;
int dx[]= {0,-1,0,1,0,0},dy[]= {-1,0,1,0,0,0},dz[] = {0,0,0,0,-1,1};
const int N = 2000010, M = N * 2;
int e[M],ne[M],w[M],h[N],idx;
int n,m;
int dist[N];
bool st[N];
void add(int a,int b,int c)
{
e[idx] = b, ne[idx] = h[a], w[idx] = c, h[a] = idx ++;
}
void dij()
{
pqp q;
q.push({0,1});
memset(dist,0x3f,sizeof dist);
dist[1] = true;
while(!q.empty()){
PII t = q.top(); q.pop();
if(st[t.y]) continue;
st[t.y] = true;
for(int i = h[t.y]; ~i ;i = ne[i]){
int j = e[i];
if(dist[j] > t.x + w[i]){
dist[j] = t.x + w[i];
q.push({dist[j],j});
}
}
}
}
void solve()
{
cin >> n >> m;
memset(h,-1,sizeof h);
for(int i = 1; i <= m; i ++){
int x,y,z; cin >> x >> y >> z;
add(x,y,z);
add(x, y + n, 0);
add(x, y + 2 * n, 2 * z);
add(x, y + 3 * n, z);
add(x + n, y + n, z);
add(x + n, y + 3 * n, 2 * z);
add(x + 2 * n, y + 2 * n, z);
add(x + 2 * n, y + 3 * n, 0);
add(x + 3 * n, y + 3 * n, z);
swap(x,y);
add(x,y,z);
add(x, y + n, 0);
add(x, y + 2 * n, 2 * z);
add(x, y + 3 * n, z);
add(x + n, y + n, z);
add(x + n, y + 3 * n, 2 * z);
add(x + 2 * n, y + 2 * n, z);
add(x + 2 * n, y + 3 * n, 0);
add(x + 3 * n, y + 3 * n, z);
}
dij();
for(int i = 2; i <= n; i ++) cout << dist[i + 3 * n] << " ";
cout << endl;
}
signed main()
{
IOS
// int _; cin >> _; while(_ --)
solve();
}

浙公网安备 33010602011771号