# CF715B. Complete The Graph

1 ≤ n ≤ 1000, 1 ≤ m ≤ 10000

#### 假做法：

spfa求s到t最短路且满足可变边最少

#### 真做法2：

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <queue>
#include <vector>
using namespace std;
typedef long long ll;
const int N = 1e5+5, M = 1e6+5;
const ll inf = 1e16;

int n, m, L, s, t;
struct edge {int u, v, ne; ll w;} e[M];
struct meow {int u, v; ll w;} a[M];
int cnt=1, h[N], mark[M];
inline void ins(int u, int v, ll w) {
if(w == 0) w=1, mark[cnt+1] = mark[cnt+2] = 1;
e[++cnt] = (edge) {u, v, h[u], w}; h[u] = cnt;
e[++cnt] = (edge) {v, u, h[v], w}; h[v] = cnt;
a[cnt>>1] = (meow) {u, v, w};
}
inline void paint(int x, ll v) {
a[x].w = v;
e[x<<1].w = e[x<<1|1].w = v;
}

ll d[N];
int inq[N], pre[N];
inline void lop(int &x) {if(x==N) x = 1;}
void spfa0(int s) {
memset(d, 0x3f, sizeof(d));
d[s] = 0; q[tail++] = s;  inq[s] = 1;
for(int i=h[u]; i; i=e[i].ne) if(!mark[i]) {
int v = e[i].v;
if(d[v] > d[u] + e[i].w) {
d[v] = d[u] + e[i].w;
if(!inq[v]) q[tail++] = v, lop(tail), inq[v] = 1;
}
}
}
}

void spfa(int s) {
memset(d, 0x3f, sizeof(d));
memset(inq, 0, sizeof(inq));
d[s] = 0; q[tail++] = s;  inq[s] = 1;
for(int i=h[u]; i; i=e[i].ne) {
int v = e[i].v;
if(d[v] > d[u] + e[i].w ) {
d[v] = d[u] + e[i].w;
pre[v] = i;
if(!inq[v]) q[tail++] = v, lop(tail), inq[v] = 1;
}
}
}
}
int chose[N];
vector<int> li;
int main() {
//freopen("in", "r", stdin);
ios::sync_with_stdio(false); cin.tie(); cout.tie();
cin >> n >> m >> L >> s >> t;
s++; t++;
for(int i=1; i<=m; i++) {
int u, v, w;
cin >> u >> v >> w;
u++; v++;
ins(u, v, w);
}
spfa0(s);
if(d[t] < L) {cout << "NO"; return 0;}
spfa(s);
if(d[t] > L) {cout << "NO"; return 0;}
if(d[t] == L) {
cout << "YES" << endl;
for(int i=1; i <= cnt>>1; i++) cout << a[i].u-1 << ' ' << a[i].v-1 << ' ' << a[i].w << '\n';
return 0;
}

int x = t;
while(x != s) {
if(mark[pre[x]]) chose[pre[x]>>1] = 1, li.push_back(pre[x]>>1);
x = e[pre[x]].u;
}
for(int i=1; i<=cnt>>1; i++) if(mark[i<<1] && !chose[i]) paint(i, inf);
for(int i=0; i<li.size(); i++) {
int now = li[i];
int delta = L - d[t] + 1;
paint(now, delta);
spfa(s);
if(d[t] == L) break;
}
cout << "YES" << endl;
for(int i=1; i <= cnt>>1; i++) cout << a[i].u-1 << ' ' << a[i].v-1 << ' ' << a[i].w << '\n';
}



ps:假做法的代码

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <queue>
using namespace std;
typedef long long ll;
const int N = 1e5+5, M = 1e6+5;
const ll inf = 1e16;

int n, m, L, s, t;
struct edge {int u, v, ne; ll w;} e[M];
struct meow {int u, v; ll w;} a[M];
int cnt=1, h[N], mark[M];
inline void ins(int u, int v, ll w) {
if(w == 0) w=1, mark[cnt+1] = mark[cnt+2] = 1;
e[++cnt] = (edge) {u, v, h[u], w}; h[u] = cnt;
e[++cnt] = (edge) {v, u, h[v], w}; h[v] = cnt;
a[cnt>>1] = (meow) {u, v, w};
}

ll d[N];
int inq[N], cou[N], pre[N];
inline void lop(int &x) {if(x==N) x = 1;}
void spfa0(int s) {
memset(d, 0x3f, sizeof(d));
d[s] = 0; q[tail++] = s;  inq[s] = 1;
for(int i=h[u]; i; i=e[i].ne) if(!mark[i]) {
int v = e[i].v;
if(d[v] > d[u] + e[i].w) {
d[v] = d[u] + e[i].w;
if(!inq[v]) q[tail++] = v, lop(tail), inq[v] = 1;
}
}
}
}
namespace test {
int pre[N];
void spfa1(int s) {
memset(d, 0x3f, sizeof(d));
d[s] = 0; q[tail++] = s;  inq[s] = 1;
for(int i=h[u]; i; i=e[i].ne) {
int v = e[i].v;
if(d[v] > d[u] + e[i].w) {
d[v] = d[u] + e[i].w;
pre[v] = i;
if(!inq[v]) q[tail++] = v, lop(tail), inq[v] = 1;
}
}
}
}
}
void spfa(int s) {
memset(d, 0x3f, sizeof(d));
memset(cou, 0x3f, sizeof(cou));
memset(inq, 0, sizeof(inq));
d[s] = 0; cou[s] = 0; q[tail++] = s;  inq[s] = 1;
for(int i=h[u]; i; i=e[i].ne) {
int v = e[i].v;
if(d[v] > d[u] + e[i].w || (d[v] == d[u]+e[i].w && cou[v] > cou[u] + mark[i])) {
d[v] = d[u] + e[i].w;
cou[v] = cou[u] + mark[i];
pre[v] = i;
if(!inq[v]) q[tail++] = v, lop(tail), inq[v] = 1;
}
}
}
}
int chose[N];
int main() {
//freopen("in", "r", stdin);
ios::sync_with_stdio(false); cin.tie(); cout.tie();
cin >> n >> m >> L >> s >> t;
s++; t++;
for(int i=1; i<=m; i++) {
int u, v, w;
cin >> u >> v >> w;
u++; v++;
ins(u, v, w);
}
spfa0(s);
if(d[t] < L) {cout << "NO"; return 0;}
spfa(s);
if(d[t] > L) {cout << "NO"; return 0;}
if(d[t] == L) {
cout << "YES" << endl;
for(int i=1; i <= cnt>>1; i++) cout << a[i].u-1 << ' ' << a[i].v-1 << ' ' << a[i].w << '\n';
return 0;
}

int x = t;
int flag = 0;
while(x != s) {
if(mark[pre[x]]) chose[pre[x]>>1] = 1, flag = pre[x] >> 1;
x = e[pre[x]].u;
}
if(!flag) {cout << "NO"; return 0;}
for(int i=1; i <= cnt>>1; i++) if(mark[i<<1] && !chose[i]) a[i].w = inf;
for(int i=1; i<=cnt; i++) if(mark[i] && !chose[i>>1]) e[i].w = inf;
int delta = L - d[t] + 1;
a[flag].w = delta;
e[flag<<1].w = e[flag<<1|1].w = delta;

test::spfa1(s);
if(d[t] != L) {
cout << d[t] << "nooooo\n";
int x = t;
while(x != s) {
if(test::pre[x] != pre[x]) {
cout << "wrong\n";
cout << mark[pre[x]] << "   " << mark[test::pre[x]] << '\n';
}
x = e[pre[x]].u;
}
}
cout << "YES" << endl;
for(int i=1; i <= cnt>>1; i++) cout << a[i].u-1 << ' ' << a[i].v-1 << ' ' << a[i].w << '\n';
}

posted @ 2018-07-09 21:55 Candy? 阅读(...) 评论(...) 编辑 收藏