目录
1. 紧急情况
题目链接:紧急情况
dijkstra多权值模板题
#include <bits/stdc++.h>
using namespace std;
const int N = 510;
int n, m, s, d;
int dist[N];
bool st[N];
int g[N][N];
int w[N];
int sum_w[N];
int path_sum[N];
void dijkstra()
{
memset(dist, 0x3f, sizeof dist);
dist[s] = 0;
sum_w[s] = w[s];
path_sum[s] = 1;
for (int i = 0; i < n; i++)
{
int t = -1;
for (int j = 0; j < n; j++)
if (!st[j] && (t == -1 || dist[t] > dist[j]))
t = j;
st[t] = true;
for (int j = 0; j < n; j++)
{
if (dist[j] > dist[t] + g[t][j])
{
dist[j] = dist[t] + g[t][j];
sum_w[j] = sum_w[t] + w[j];
path_sum[j] = path_sum[t];
}
else if (dist[j] == dist[t] + g[t][j])
{
path_sum[j] += path_sum[t];
sum_w[j] = max(sum_w[j], sum_w[t] + w[j]);
}
}
}
cout << path_sum[d] << ' ' << sum_w[d] << endl;
}
int main()
{
cin >> n >> m >> s >> d;
memset(g, 0x3f, sizeof g);
for (int i = 0; i < n; i++)cin >> w[i];
while (m--)
{
int a, b, c;
cin >> a >> b >> c;
g[a][b] = g[b][a] = min(g[a][b], c);
}
dijkstra();
}
2. 旅行计划
#include <bits/stdc++.h>
using namespace std;
int n, m, s, d;
const int N = 510;
int g[N][N];
int w[N][N];
int dist[N];
int cost[N];
bool st[N];
int pre[N];
void dijkstra()
{
memset(dist, 0x3f, sizeof dist);
memset(cost, 0x3f, sizeof cost);
dist[s] = 0;
cost[s] = 0;
for (int i = 0; i < n; i++)
{
int t = -1;
for (int j = 0; j < n; j++)
if (!st[j] && (t == -1 || dist[t] > dist[j]))
t = j;
st[t] = true;
for (int j = 0; j < n; j++)
{
if (dist[j] > dist[t] + g[t][j])
{
dist[j] = dist[t] + g[t][j];
cost[j] = cost[t] + w[t][j];
pre[j] = t;
}
else if (dist[j] == dist[t] + g[t][j])
{
if (cost[j] > cost[t] + w[t][j])
{
cost[j] = cost[t] + w[t][j];
pre[j] = t;
}
}
}
}
stack<int>stk;
int u = d;
while (u != s)
{
stk.push(u);
u = pre[u];
}
stk.push(s);
while (stk.size())
{
cout << stk.top() << ' ';
stk.pop();
}
cout<<dist[d]<<' '<<cost[d];
}
int main()
{
cin >> n >> m >> s >> d;
memset(g, 0x3f, sizeof g);
memset(w, 0x3f, sizeof w);
while (m--)
{
int a, b, c, d;
cin >> a >> b >> c >> d;
g[a][b] = g[b][a] = min(g[a][b], c);
w[a][b] = w[b][a] = min(w[a][b], d);
}
dijkstra();
return 0;
}
3. 团伙头目
#include <bits/stdc++.h>
using namespace std;
int n, k;
unordered_map<string, vector<pair<string, int>>>g;
unordered_map<string, int>total;
unordered_map<string, bool>st;
int dfs(string ver, vector<string>& nodes)
{
st[ver] = true;
nodes.push_back(ver);
int sum = 0;
for (auto edge : g[ver])
{
sum += edge.second;
string cur = edge.first;
if (!st[cur])sum += dfs(cur, nodes);
}
return sum;
}
int main()
{
cin >> n >> k;
while (n--)
{
string a, b;
int t;
cin >> a >> b >> t;
g[a].push_back({ b,t });
g[b].push_back({ a,t });
total[a] += t;
total[b] += t;
}
vector<pair<string, int>>res;
for (auto item : total)
{
string ver = item.first;
vector<string>nodes;
int sum = dfs(ver, nodes) /2;//这里为什么/2
if (nodes.size() > 2 && sum > k)
{
string boss = nodes[0];
for (string node : nodes)
if (total[boss] < total[node])
boss = node;
res.push_back({ boss,(int)nodes.size() });
}
}
sort(res.begin(), res.end());
cout << res.size() << endl;
for (auto item : res)cout << item.first << ' ' << item.second << endl;
return 0;
}
4. 条条大路通罗马
#include <bits/stdc++.h>
using namespace std;
const int N = 210;
int n, m;
int g[N][N];
int dist[N];
bool st[N];
int w[N];
string city[N];
int cnt[N];
int cost[N];
int sum[N];
int pre[N];
unordered_map<string, int>mp;
void dijkstra()
{
memset(dist, 0x3f, sizeof dist);
dist[1] = 0;
cnt[1] = 1;
for (int i = 1; i <= n; i++)
{
int t = -1;
for (int j = 1; j <= n; j++)
if (!st[j] && (t == -1 || dist[t] > dist[j]))
t = j;
st[t] = true;
for (int j = 1; j <= n; j++)
{
if (dist[j] > dist[t] + g[t][j])
{
dist[j] = dist[t] + g[t][j];
cnt[j] = cnt[t];
sum[j] = sum[t] + 1;
cost[j] = cost[t] + w[j];
pre[j] = t;
}
else if (dist[j] == dist[t] + g[t][j])
{
cnt[j] += cnt[t];
if (cost[j] < cost[t] + w[j])
{
cost[j] = cost[t] + w[j];
sum[j] = sum[t] + 1;
pre[j] = t;
}
else if (cost[j] == cost[t] + w[j])
{
if (sum[j] > sum[t] + 1)
{
sum[j] = sum[t] + 1;
pre[j] = t;
}
}
}
}
}
}
int main()
{
memset(g, 0x3f, sizeof g);
cin >> n >> m >> city[1];
mp[city[1]] = 1;
for(int i=2;i<=n;i++)
{
cin >> city[i] >> w[i];
mp[city[i]] = i;
}
while (m--)
{
string x, y;
int c;
cin >> x >> y >> c;
int a = mp[x], b = mp[y];
g[a][b] = g[b][a] = min(g[a][b], c);
}
dijkstra();
int ed = mp["ROM"];
cout << cnt[ed] << ' ' << dist[ed] << ' ' << cost[ed] << ' ' << cost[ed] / sum[ed] << endl;
stack<int>stk;
int u = ed;
while (u != 1)
{
stk.push(u);
u = pre[u];
}
stk.push(1);
bool f = false;
while (stk.size())
{
if (f)cout << "->";
f = true;
cout << city[stk.top()];
stk.pop();
}
return 0;
}
5. 在线地图
#include <bits/stdc++.h>
using namespace std;
const int N = 510, M = N * N;
int n, m, S, T;
int h[N], e[M], w1[M], w2[M], ne[M], idx;
int dist1[N], dist2[N], pre[N];
bool st[N];
void add(int a, int b, int c, int d)
{
e[idx] = b, w1[idx] = c, w2[idx] = d, ne[idx] = h[a], h[a] = idx++;
}
pair<int, string>dijkstra(int w1[], int w2[], int type)
{
memset(dist1, 0x3f, sizeof dist1);
memset(dist2, 0x3f, sizeof dist2);
memset(st, false, sizeof st);
dist1[S] = dist2[S] = 0;
for (int i = 0; i < n; i++)
{
int t = -1;
for (int j = 0; j < n; j++)
if (!st[j] && (t == -1 || dist1[t] > dist1[j]))
t = j;
st[t] = true;
for (int u = h[t]; ~u; u = ne[u])
{
int j = e[u];
int cost;
if (type == 0)cost = w2[u];
else cost = 1;
if (dist1[j] > dist1[t] + w1[u])
{
dist1[j] = dist1[t] + w1[u];
dist2[j] = dist2[t] + cost;
pre[j] = t;
}
else if (dist1[j] == dist1[t] + w1[u])
{
if (dist2[j] > dist2[t] + cost)
{
dist2[j] = dist2[t] + cost;
pre[j] = t;
}
}
}
}
stack<int>stk;
int u = T;
while (u != S)
{
stk.push(u);
u = pre[u];
}
pair<int, string>res;
res.first = dist1[T];
res.second = to_string(S);
while (stk.size())
{
res.second += " -> " + to_string(stk.top());
stk.pop();
}
return res;
}
int main()
{
cin >> n >> m;
memset(h, -1, sizeof h);
while (m--)
{
int a, b, t, c, d;
cin >> a >> b >> t >> c >> d;
add(a, b, c, d);
if (!t)add(b, a, c, d);
}
cin >> S >> T;
auto A = dijkstra(w1, w2, 0);
auto B = dijkstra(w2, w1, 1);
if (A.second != B.second)
{
printf("Distance = %d: %s
", A.first, A.second.c_str());
printf("Time = %d: %s
", B.first, B.second.c_str());
}
else
printf("Distance = %d; Time = %d: %s
", A.first, B.first, A.second.c_str());
return 0;
}
6. 哈密顿回路
#include <bits/stdc++.h>
using namespace std;
const int N = 210;
int n, m;
bool g[N][N], st[N];
int nodes[N * 2];
bool check(int cnt)
{
if (nodes[0] != nodes[cnt - 1] || cnt != n + 1)return false;
memset(st, 0, sizeof st);
for(int i=0;i<cnt-1;i++)
{
st[nodes[i]] = true;
if (!g[nodes[i]][nodes[i + 1]])
return false;
}
for (int i = 1; i <= n; i++)
if (!st[i])
return false;
return true;
}
int main()
{
cin >> n >> m;
while (m--)
{
int a, b;
cin >> a >> b;
g[a][b] = g[b][a] = true;
}
int k;
cin >> k;
while (k--)
{
int cnt;
cin >> cnt;
for (int i = 0; i < cnt; i++)cin >> nodes[i];
if (check(cnt))puts("YES");
else puts("NO");
}
return 0;
}
7. 欧拉路径
#include <bits/stdc++.h>
using namespace std;
const int N = 510;
int n, m;
bool g[N][N], st[N];
int d[N];
int dfs(int u)
{
st[u] = true;
int res = 1;
for (int i = 1; i <= n; i++)
if (!st[i] && g[u][i])res += dfs(i);
return res;
}
int main()
{
cin >> n >> m;
for (int i = 0; i < m; i++)
{
int a, b;
cin >> a >> b;
g[a][b] = g[b][a] = true;
d[a]++, d[b]++;
}
int cnt = dfs(1);
for (int i = 1; i <= n; i++)cout << d[i] << ' ';
cout << endl;
if (cnt == n)
{
int s = 0;
for (int i = 1; i <= n; i++)
{
if (d[i] % 2)s++;
}
if (s == 0)puts("Eulerian");
else if (s == 2)puts("Semi-Eulerian");
else puts("Non-Eulerian");
}
else puts("Non-Eulerian");
return 0;
}
8. 地铁地图
#include <bits/stdc++.h>
using namespace std;
#define x first
#define y second
typedef pair<int, int>PII;
const int N = 10010, M = 1000010;
int n;
int h[N], e[M], ne[M], w[M], line[M], idx;
int dist[N], cnt[N], pre[N];
int stops[N];
string info[N];
bool st[N];
string get_number(int x)
{
string res = to_string(x);
while (res.size() < 4)res = '0' + res;
return res;
}
void add(int a, int b, int c, int id)
{
e[idx] = b, w[idx] = c, line[idx] = id, ne[idx] = h[a], h[a] = idx++;
}
void dijkstra(int start, int end)
{
memset(dist, 0x3f, sizeof dist);
memset(cnt, 0x3f, sizeof cnt);
memset(st, 0, sizeof st);
priority_queue<PII, vector<PII>, greater<PII>>heap;
dist[start] = cnt[start] = 0;
heap.push({ 0, start });
while (heap.size())
{
auto t = heap.top();
heap.pop();
if (t.y == end)break;
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] > dist[t.y] + w[i])
{
dist[j] = dist[t.y] + w[i];
cnt[j] = cnt[t.y] + 1;
pre[j] = t.y;
info[j]= "Take Line#" + to_string(line[i]) + " from " +
get_number(t.y) + " to " + get_number(j) + ".";
heap.push({ dist[j],j });
}
else if (dist[j] == dist[t.y] + w[i])
{
if (cnt[j] > cnt[t.y] + 1)
{
cnt[j] = cnt[t.y] + 1;
pre[j] = t.y;
info[j]="Take Line#" + to_string(line[i]) + " from " +
get_number(t.y) + " to " + get_number(j) + ".";
}
}
}
}
cout << dist[end] << endl;
stack<string>stk;
int u = end;
while (u != start)
{
stk.push(info[u]);
u = pre[u];
}
while (stk.size())
{
cout << stk.top() << endl;
stk.pop();
}
}
int main()
{
cin >> n;
memset(h, -1, sizeof h);
for (int i = 1; i <= n; i++)
{
int m;
cin >> m;
for (int j = 0; j < m; j++)cin >> stops[j];
for (int j = 0; j < m; j++)
{
for (int k = 0; k < j; k++)
{
int len;
if (stops[0] != stops[m - 1])len = j - k;
else len = min(j - k, k + m - 1 - j);
add(stops[j], stops[k], len, i);
add(stops[k], stops[j], len, i);
}
}
}
int k;
cin >> k;
while (k--)
{
int start, end;
cin >> start >> end;
dijkstra(start, end);
}
return 0;
}
9. 顶点覆盖
#include <bits/stdc++.h>
using namespace std;
const int N = 2e4 + 10;
struct node
{
int a, b;
}e[N];
int n, m;
int main()
{
cin >> n >> m;
for (int i = 0; i < m; i++)cin >> e[i].a >> e[i].b;
int k;
cin >> k;
while (k--)
{
int cnt;
unordered_map<int, bool>mp;
cin >> cnt;
while (cnt--)
{
int x;
cin >> x;
mp[x] = true;
}
bool f = false;
for (int i = 0; i < m; i++)
{
if (!mp[e[i].a] && !mp[e[i].b])
{
f = true;
break;
}
}
if (!f)puts("Yes");
else puts("No");
}
return 0;
}
10. 第一次接触
#include <bits/stdc++.h>
using namespace std;
const int N = 310;
int n, m;
unordered_map<string, int>mp;
string num[N];
int id;
bool g[N][N];
vector<int>boys, girls;
int main()
{
cin >> n >> m;
char as[N], bs[N];
while (m--)
{
string a, b;
cin >> as >> bs;
a = as, b = bs;
string x = a, y = b;
if (x.size() == 5)x = x.substr(1);
if (y.size() == 5)y = y.substr(1);
if (!mp.count(x))mp[x] = ++id, num[id] = x;
if (!mp.count(y))mp[y] = ++id, num[id] = y;
int px = mp[x], py = mp[y];
g[px][py] = g[py][px] = true;
if (a[0] != '-')boys.push_back(px);
else girls.push_back(px);
if (b[0] != '-')boys.push_back(py);
else girls.push_back(py);
}
sort(boys.begin(), boys.end());
boys.erase(unique(boys.begin(), boys.end()), boys.end());
sort(girls.begin(), girls.end());
girls.erase(unique(girls.begin(), girls.end()), girls.end());
int k;
cin >> k;
while (k--)
{
vector<pair<string, string>>res;
string x, y;
cin >> as >> bs;
x = as, y = bs;
vector<int>p = boys, q = boys;
if (x[0] == '-')p = girls, x = x.substr(1);
if (y[0] == '-')q = girls, y = y.substr(1);
int a = mp[x], b = mp[y];
for(auto c:p)
for (auto d : q)
{
if (c != a && c != b && d != a && d != b && g[a][c] && g[c][d] && g[d][b])
res.push_back({ num[c],num[d] });
}
sort(res.begin(), res.end());
printf("%d
", res.size());
for (auto x : res)printf("%s %s
", x.first.c_str(), x.second.c_str());
}
return 0;
}
11. 最大集团
#include <bits/stdc++.h>
using namespace std;
const int N = 210, M = N * N;
int n, m;
int g[N][N];
bool st[N];
vector<int>v;
bool check1(int cnt)
{
for (int i = 0; i < cnt; i++)
for (int j = 0; j < i; j++)
if (g[v[i]][v[j]] == 0)return false;
return true;
}
bool check2(int cnt)
{
for (int i = 0; i < cnt; i++)
st[v[i]] = true;
for (int i = 1; i <= n; i++)
{
if (!st[i])
{
bool f = false;
for (int j = 0; j < cnt; j++)
{
if (!g[v[j]][i])
{
f = true;
break;
}
}
if (!f)return false;
}
}
return true;
}
int main()
{
cin >> n >> m;
for (int i = 1; i <= m; i++)
{
int a, b;
cin >> a >> b;
g[a][b] = g[b][a] = 1;
}
int k;
cin >> k;
while (k--)
{
int cnt;
cin >> cnt;
memset(st, false, sizeof st);
for (int i = 0; i < cnt; i++)
{
int x;
cin >> x;
v.push_back(x);
}
if (check1(cnt))
{
if (check2(cnt))puts("Yes");
else puts("Not Maximal");
}
else puts("Not a Clique");
v.clear();
}
return 0;
}
12. 拓扑顺序
#include <bits/stdc++.h>
using namespace std;
const int N = 1010;
const int M = 20010;
int h[N], e[M], ne[M], idx;
int n, m, k;
int d[N];
int backup[N];
void add(int a, int b)
{
e[idx] = b, ne[idx] = h[a], h[a] = idx++;
}
int main()
{
memset(h, -1, sizeof h);
cin >> n >> m;
while (m--)
{
int a, b;
cin >> a >> b;
add(a, b);
d[b]++;
}
cin >> k;
for (int i = 0; i < k; i++)
{
vector<int>v;
bool f = false;
memcpy(backup,d,sizeof d);
for (int j = 0; j < n; j++)
{
int x;
cin >> x;
v.push_back(x);
}
for (auto x : v)
{
if (backup[x])
{
f = true;
break;
}
for (int j = h[x]; ~j; j = ne[j])
{
int c = e[j];
backup[e[j]]--;
}
}
if (f)cout << i << ' ';
}
return 0;
}
13. 旅行商问题
#include <bits/stdc++.h>
using namespace std;
const int N = 210, INF = 0x3f3f3f3f;
int n, m;
int d[N][N], vers[310];
bool st[N];
int main()
{
cin >> n >> m;
memset(d, 0x3f, sizeof d);
for (int i = 0; i < m; i++)
{
int a, b, c;
cin >> a >> b >> c;
d[a][b] = d[b][a] = c;
}
int k;
cin >> k;
int minv = INF, min_id;
for (int t = 1; t <= k; t++)
{
memset(st, false, sizeof st);
int cnt;
cin >> cnt;
for (int i = 0; i < cnt; i++)cin >> vers[i];
int sum = 0;
bool f = false;
for (int i = 0; i + 1 < cnt; i++)
{
int a = vers[i], b = vers[i + 1];
if (d[a][b] == INF)
{
sum = -1;
f = true;
break;
}
else sum += d[a][b];
st[a] = true;
}
for (int i = 1; i <= n; i++)
if (!st[i])
{
f = true;
break;
}
if (vers[0] != vers[cnt - 1])f = true;
if (sum == -1) printf("Path %d: NA (Not a TS cycle)
", t);
else
{
if (f)printf("Path %d: %d (Not a TS cycle)
", t, sum);
else
{
if (cnt == n + 1)printf("Path %d: %d (TS simple cycle)
", t, sum);
else printf("Path %d: %d (TS cycle)
", t, sum);
if (minv > sum)
{
minv = sum;
min_id = t;
}
}
}
}
printf("Shortest Dist(%d) = %d
", min_id, minv);
return 0;
}
14. 顶点着色
#include <bits/stdc++.h>
using namespace std;
const int N = 1e4 + 10;
struct node
{
int a, b;
}e[N];
int n, m;
int colors[N];
int main()
{
cin >> n >> m;
for (int i = 0; i < m; i++)cin >> e[i].a >> e[i].b;
int k;
cin >> k;
while (k--)
{
bool f = false;
for (int i = 0; i < n; i++)cin >> colors[i];
for (int i = 0; i < m; i++)
{
if (colors[e[i].a] == colors[e[i].b])
{
f = true;
break;
}
}
if (!f)
{
set<int>s;
for (int i = 0; i < n; i++)s.insert(colors[i]);
printf("%d-coloring
", s.size());
}
else puts("No");
}
return 0;
}
15. 公共自行车管理
在这里插入代码片
16. 加油站
#include <bits/stdc++.h>
using namespace std;
const int N = 1010, M = 100010;
int n, m;
int h[N], e[M], ne[M], idx;
bool st[N];
void add(int a, int b)
{
e[idx] = b, ne[idx] = h[a], h[a] = idx++;
}
int bfs(int start)
{
memset(st, false, sizeof st);
queue<int>q;
q.push(start);
st[start] = true;
int cnt = 0;
int res = 0;
while (q.size())
{
int sz = q.size();
if (cnt == m)break;
res += sz;
for (int i = 0; i < sz; i++)
{
auto t = q.front();
q.pop();
for (int j = h[t]; ~j; j = ne[j])
{
if (st[e[j]])continue;
q.push(e[j]);
st[e[j]] = true;
}
}
cnt++;
}
return res + q.size() - 1;
}
int main()
{
cin >> n >> m;
memset(h, -1, sizeof h);
for (int i = 1; i <= n; i++)
{
int cnt;
cin >> cnt;
while (cnt--)
{
int x;
cin >> x;
add(x, i);
}
}
int k;
cin >> k;
while (k--)
{
int x;
cin >> x;
cout << bfs(x) << endl;
}
return 0;
}
17. 微博转发
#include <bits/stdc++.h>
using namespace std;
const int N = 1010, M = 100010;
int n, m;
int h[N], e[M], ne[M], idx;
bool st[N];
void add(int a, int b)
{
e[idx] = b, ne[idx] = h[a], h[a] = idx++;
}
int bfs(int start)
{
memset(st, false, sizeof st);
queue<int>q;
q.push(start);
st[start] = true;
int cnt = 0;
int res = 0;
while (q.size())
{
int sz = q.size();
if (cnt == m)break;
res += sz;
for (int i = 0; i < sz; i++)
{
auto t = q.front();
q.pop();
for (int j = h[t]; ~j; j = ne[j])
{
if (st[e[j]])continue;
q.push(e[j]);
st[e[j]] = true;
}
}
cnt++;
}
return res + q.size() - 1;
}
int main()
{
cin >> n >> m;
memset(h, -1, sizeof h);
for (int i = 1; i <= n; i++)
{
int cnt;
cin >> cnt;
while (cnt--)
{
int x;
cin >> x;
add(x, i);
}
}
int k;
cin >> k;
while (k--)
{
int x;
cin >> x;
cout << bfs(x) << endl;
}
return 0;
}