分层图题目
P9504 『MGOI』Simple Round I | C. 魔法禁林
Link
\(w \leqslant 100\) ,当 \(k>100\) 时,\(\lfloor\frac{n}{k}\rfloor\) 始终为 \(0\) 。
以 \(\lfloor\frac{n}{k}\rfloor\) 为层数建图。
#include <iostream>
#include <queue>
#include <cmath>
#define MAXN 80010
#define MA 105
using namespace std;
const int inf = 2147483647;
int n,m,s,t,cnt;
int dis[MAXN][105],h[MAXN],to[MAXN],val[MAXN],nxt[MAXN];
bool vis[MAXN][105];
int maxw;
struct node {
int v,w,k;
friend bool operator < (node a,node b) {
return a.w > b.w;
}
} tmp;
priority_queue <node> q;
void add(int a,int b,int c) {
to[++cnt] = b;
val[cnt] = c;
nxt[cnt] = h[a];
h[a] = cnt;
}
void dijkstra() {
for(int i = 1;i <= n;++ i)
for(int j = 0;j <= 101;++ j)
dis[i][j] = inf;
dis[s][0] = 0;
tmp.v = s;tmp.w = 0;tmp.k = 0;q.push(tmp);
while(!q.empty()) {
int u = q.top().v,k = q.top().k;
q.pop();
if(vis[u][k]) continue;
vis[u][k] = 1;
for(int i = h[u];i;i = nxt[i]) {
if(dis[to[i]][min(101,k + 1)] > (long long)dis[u][min(101,k)] + val[i] / (k + 1)) {
dis[to[i]][min(101,k + 1)] = dis[u][min(101,k)] + val[i] / (k + 1);
tmp.k = k + 1;
tmp.w = dis[to[i]][min(101,k + 1)];
tmp.v = to[i];
q.push(tmp);
}
}
}
}
int main() {
cin >> n >> m >> s >> t;
swap(s,t);
int u,v,w;
for(int i = 1;i <= m;++ i) {
cin >> u >> v >> w;
add(u,v,w);
add(v,u,w);
maxw = max(maxw,w);
}
dijkstra();
int minn = inf;
for(int i = 0;i <= 100;++ i) minn = min(minn,dis[t][i]);
cout << minn;
return 0;
}
P1073 [NOIP2009 提高组] 最优贸易
Link
建三层图。
购入是到第二层图,卖出时到第三层图。
每层之间的长度为该点的价格,每层中点之间的路径长度为 \(0\) 。
因为存在负边权,不能使用 dijkstra ,应使用 spfa 。
#include <iostream>
#include <cstdio>
#include <queue>
#include <cmath>
using namespace std;
#define MAXN 100005
#define MAXM 500005
#define inf 2147483647
int n,m,h[MAXN * 3],val[MAXM * 5],nxt[MAXM * 5],cnt,c[MAXN],to[MAXM * 5],dis[MAXN * 3];
bool vis[MAXN * 3];
queue <int> q;
void add(int x,int y,int z) {
nxt[++cnt] = h[x];
val[cnt] = z;
to[cnt] = y;
h[x] = cnt;
}
void spfa() {
for(int i = 1;i <= n * 3;++ i) dis[i] = -inf;
dis[1] = 0;
q.push(1);
while(!q.empty()) {
int u = q.front();
q.pop();
vis[u] = false;
for(int i = h[u];i;i = nxt[i]) {
if(dis[to[i]] < dis[u] + val[i]) {
dis[to[i]] = dis[u] + val[i];
if(!vis[to[i]]) {q.push(to[i]);vis[to[i]] = true;}
}
}
}
return ;
}
int main() {
scanf("%d%d",&n,&m);
for(int i = 1;i <= n;++ i) scanf("%d",&c[i]);
for(int x,y,z,i = 1;i <= m;++ i) {
scanf("%d%d%d",&x,&y,&z);
add(x,y,0);
add(x + n,y + n,0);
add(x + n * 2,y + n * 2,0);
if(z == 2) {
add(y,x,0);
add(y + n,x + n,0);
add(y + n * 2,x + n * 2,0);
}
}
for(int i = 1;i <= n;++ i) {
add(i,i + n,-c[i]);
add(i + n,i + n * 2,c[i]);
}
spfa();
cout << max(0,dis[n * 3]);
return 0;
}
P4568 [JLOI2011] 飞行路线
Link
建 \(k\) 层,每层之间用 \(0\) 连接。
#include <iostream>
#include <cstdio>
#include <cmath>
#include <queue>
using namespace std;
#define MAXN 100005
#define MAXM 500004
#define inf 2147483647
int s,t,n,m,k,cnt;
int h[MAXN * 10],dis[MAXN * 10];
bool v[MAXN * 10];
struct edge {
int val;
int to;
int nxt;
} e[MAXM * 10];
struct node {
int val;
int id;
bool friend operator < (node a,node b) {
return a.val > b.val;
}
} tmp;
priority_queue <node> q;
void add(int x,int y,int z) {
e[++cnt].val = z;
e[cnt].to = y;
e[cnt].nxt = h[x];
h[x] = cnt;
}
void dijkstra() {
for(int i = 0;i <= n * k + n;++ i) dis[i] = inf;
dis[s] = 0;
tmp.val = 0;tmp.id = s;
q.push(tmp);
while(!q.empty()) {
int u = q.top().id;
q.pop();
if(v[u]) continue;
v[u] = true;
for(int i = h[u];i;i = e[i].nxt) {
if(dis[u] + e[i].val < dis[e[i].to]) {
dis[e[i].to] = dis[u] + e[i].val;
tmp.val = dis[e[i].to];tmp.id = e[i].to;
q.push(tmp);
}
}
}
return ;
}
int main() {
scanf("%d%d%d",&n,&m,&k);
scanf("%d%d",&s,&t);
for(int i = 1,x,y,z;i <= m;++ i) {
scanf("%d%d%d",&x,&y,&z);
add(x,y,z);
add(y,x,z);
for(int j = 1;j <= k;++ j) {
add(x + j * n - n,y + j * n,0);
add(y + j * n - n,x + j * n,0);
add(x + j * n,y + j * n,z);
add(y + j * n,x + j * n,z);
}
}
dijkstra();
int ans = inf;
for(int i = 0;i <= k;++ i) ans = min(ans,dis[t + i * n]);
cout << ans;
return 0;
}
P2939 [USACO09FEB] Revamping Trails G
Link
同上。
#include <iostream>
#include <cstdio>
#include <cmath>
#include <queue>
using namespace std;
#define MAXN 100005
#define MAXM 500004
#define inf 2147483647
int s,t,n,m,k,cnt;
int h[MAXN * 10],dis[MAXN * 10];
bool v[MAXN * 10];
struct edge {
int val;
int to;
int nxt;
} e[MAXM * 10];
struct node {
int val;
int id;
bool friend operator < (node a,node b) {
return a.val > b.val;
}
} tmp;
priority_queue <node> q;
void add(int x,int y,int z) {
e[++cnt].val = z;
e[cnt].to = y;
e[cnt].nxt = h[x];
h[x] = cnt;
}
void dijkstra() {
for(int i = 0;i <= n * k + n;++ i) dis[i] = inf;
dis[s] = 0;
tmp.val = 0;tmp.id = s;
q.push(tmp);
while(!q.empty()) {
int u = q.top().id;
q.pop();
if(v[u]) continue;
v[u] = true;
for(int i = h[u];i;i = e[i].nxt) {
if(dis[u] + e[i].val < dis[e[i].to]) {
dis[e[i].to] = dis[u] + e[i].val;
tmp.val = dis[e[i].to];tmp.id = e[i].to;
q.push(tmp);
}
}
}
return ;
}
int main() {
scanf("%d%d%d",&n,&m,&k);
for(int i = 1,x,y,z;i <= m;++ i) {
scanf("%d%d%d",&x,&y,&z);
add(x,y,z);
add(y,x,z);
for(int j = 1;j <= k;++ j) {
add(x + j * n - n,y + j * n,0);
add(y + j * n - n,x + j * n,0);
add(x + j * n,y + j * n,z);
add(y + j * n,x + j * n,z);
}
}
s = 1;t = n;
dijkstra();
int ans = inf;
for(int i = 0;i <= k;++ i) ans = min(ans,dis[t + i * n]);
cout << ans;
return 0;
}
P4822 [BJWC2012] 冻结
Link
同上。
#include <iostream>
#include <cstdio>
#include <cmath>
#include <queue>
using namespace std;
#define MAXN 100005
#define MAXM 500004
#define inf 2147483647
int s,t,n,m,k,cnt;
int h[MAXN * 10],dis[MAXN * 10];
bool v[MAXN * 10];
struct edge {
int val;
int to;
int nxt;
} e[MAXM * 10];
struct node {
int val;
int id;
bool friend operator < (node a,node b) {
return a.val > b.val;
}
} tmp;
priority_queue <node> q;
void add(int x,int y,int z) {
e[++cnt].val = z;
e[cnt].to = y;
e[cnt].nxt = h[x];
h[x] = cnt;
}
void dijkstra() {
for(int i = 0;i <= n * k + n;++ i) dis[i] = inf;
dis[s] = 0;
tmp.val = 0;tmp.id = s;
q.push(tmp);
while(!q.empty()) {
int u = q.top().id;
q.pop();
if(v[u]) continue;
v[u] = true;
for(int i = h[u];i;i = e[i].nxt) {
if(dis[u] + e[i].val < dis[e[i].to]) {
dis[e[i].to] = dis[u] + e[i].val;
tmp.val = dis[e[i].to];tmp.id = e[i].to;
q.push(tmp);
}
}
}
return ;
}
int main() {
scanf("%d%d%d",&n,&m,&k);
for(int i = 1,x,y,z;i <= m;++ i) {
scanf("%d%d%d",&x,&y,&z);
add(x,y,z);
add(y,x,z);
for(int j = 1;j <= k;++ j) {
add(x + j * n - n,y + j * n,z / 2);
add(y + j * n - n,x + j * n,z / 2);
add(x + j * n,y + j * n,z);
add(y + j * n,x + j * n,z);
}
}
s = 1;t = n;
dijkstra();
int ans = inf;
for(int i = 0;i <= k;++ i) ans = min(ans,dis[t + i * n]);
cout << ans;
return 0;
}

浙公网安备 33010602011771号