kuangbin_ShortPath S (POJ 3169)

时间:2023-03-09 05:45:40
kuangbin_ShortPath S (POJ 3169)

被cow类题目弄得有些炸裂 想了好久好久写了120多行 依然长跪不起发现计算约束条件的时候还是好多麻烦的地方过不去

然后看了看kuangbin的blog 都是泪啊 差分约束的方式做起来只要70多行啊炒鸡简洁有没有

Ps 给手写queue的实现方式跪一下 真是快的飞起

------------------Update-------------------

虽然当时也感叹了一下为什么用最短路的写法解最长路但是没深究 但是看了奚政巨巨的odp(什么鬼格式)之后发现原来一切都来自神奇的差分约束

约束条件是dist[i] - dist[j] <= c 等价于if(dist[i] > c + dist[j]) dist[i] 就被松弛成dist[j] + c 都是算计啊!

妙 真是妙(脑补鬼畜)

 #include <cstdio>
#include <cmath>
#include <cstring>
#include <queue>
#include <algorithm>
#define INF 0x3F3F3F3F
using namespace std; const int MAXN = (int)(1e4 + );
const int MAXM = (int)(1e5 + ); int n, ml, md, dist[MAXN];
int size, head[MAXN], point[MAXM], val[MAXM], nxt[MAXM]; void add (int from, int to, int value)
{
val[size] = value;
point[size] = to;
nxt[size] = head[from];
head[from] = size++;
} int spfa()
{
int time[MAXN];//也许以后用cnt做名字比较好
bool vis[MAXN];
queue<int> q;
memset(vis, false, sizeof vis);
memset(dist, INF, sizeof dist);
memset(time, , sizeof time); q.push();
vis[] = true;
dist[] = ;
while(!q.empty()){
int u = q.front();
q.pop();
vis[u] = false;
for(int i = head[u]; ~i; i = nxt[i]){
if(dist[point[i]] > dist[u] + val[i]){
dist[point[i]] = dist[u] + val[i];
if(!vis[point[i]]){
vis[point[i]] = true;
q.push(point[i]);
if(++time[point[i]] > n) return -;
}
}
}
}
return dist[n] == INF ? - : dist[n];
} int main()
{
size = ;
memset(head, -, sizeof head); scanf("%d%d%d", &n, &ml, &md);
while(ml--){
int from, to, value;
scanf("%d%d%d", &from, &to, &value);
if(from > to) swap(from, to);
add(from, to, value);
}
while(md--){
int from, to, value;
scanf("%d%d%d", &from, &to, &value);
if(from < to) swap(from, to);
add(from, to, -value);
}
int ans = spfa();
printf("%d\n", ans);
return ;
}