旅游路线问题
#include <iostream>在这里插入图片描述#include <cstring>
#include <map>
#include <queue>
using namespace std;
using std::cout;
const int INF = 1000000;
const int NODESIZE = 100;
const int EDGESIZE = 10000;
int top;
int maxflow;
bool vis[NODESIZE];
int c[NODESIZE];
int dist[NODESIZE];
int pre[NODESIZE];
string str[NODESIZE];
map<string, int> maze;struct Vertex
{ int first;
} V[NODESIZE];
struct Edge
{ int v, next; int cap, flow, cost;
} E[EDGESIZE];void init();
void add(int u, int v, int c, int cost);
void add_edge(int u, int v, int c, int cost);
void printgraph(int n);
void printflow(int n);
int MCMF(int s, int t, int n);
bool SPFA(int s, int t, int n);
void print(int s, int t);int main(int argc, char **argv)
{int n, m, i;string str1, str2;cout << "输入景点个数n和直达路线数m:\n";cin >> n >> m;init();maze.clear();cout << "输入景点名字\n";for (i = 1; i <= n; i++){cin >> str[i];maze[str[i]] = i;if (i == 1 || i == n){add(i, i + n, 2, 0);}else{add(i, i + n, 1, 0);}}cout << "输入可以直达的两个景点名\n";for (i = 1; i <= m; i++){cin >> str1 >> str2;int a = maze[str1], b = maze[str2];if (a < b){if (a == 1 && b == n){add(a + n, b, 2, -1);}else{add(a + n, b, 1, -1);}}else{if (b == 1 && a == n){add(b + n, a, 2, -1);}else{add(b + n, a, 1, -1);}}}cout << "最多经过景点个数:" << 0 - MCMF(1, 2 * n, 2 * n) << endl;cout << "依次经过景点:\n";cout << str[1] << endl;memset(vis, 0, sizeof(vis));print(1, n);cout << str[1] << endl;return 0;
}
void init()
{memset(V, -1, sizeof(V)); top = 0; maxflow = 0;
}
void add(int u, int v, int c, int cost)
{add_edge(u, v, c, cost);add_edge(v, u, 0, -cost);
}
void add_edge(int u, int v, int c, int cost)
{E[top].v = v;E[top].cap = c;E[top].flow = 0;E[top].cost = cost;E[top].next = V[u].first; V[u].first = top++;
}
void printgraph(int n)
{cout << "\n网络邻接表\n";for (int i = 1; i <= n; i++){cout << "v" << i << " [" << V[i].first;for (int j = V[i].first; ~j; j = E[j].next){cout << "]--[" << E[j].v << " " << E[j].cap << " "<< E[j].flow << " " << E[j].cost << " " << E[j].next << "]\n";}cout << "\n";}
}
void printflow(int n)
{cout << "实流边:\n";for (int i = 1; i <= n; i++){for (int j = V[i].first; ~j; j = E[j].next){if (E[j].flow > 0){cout << "v" << i << "--"<< "v" << E[j].v << " " << E[j].flow << " " << E[j].cost << "\n";}}}
}
int MCMF(int s, int t, int n)
{int d; int i, mincost;mincost = 0; while (SPFA(s, t, n)){ d = INF; cout << "增广路径: " << t; for (i = pre[t]; i != -1; i = pre[E[i ^ 1].v]){ d = min(d, E[i].cap - E[i].flow); cout << "--" << E[i ^ 1].v;}cout << "\n";cout << "增流量: " << d << "\n";maxflow += d;for (int i = pre[t]; i != -1; i = pre[E[i ^ 1].v]){E[i].flow += d;E[i ^ 1].flow -= d;}mincost += dist[t] * d; }return mincost;
}
bool SPFA(int s, int t, int n)
{int u, v;queue<int> qu; memset(vis, false, sizeof(vis)); memset(c, 0, sizeof(c)); memset(pre, -1, sizeof(pre)); for (int i = 1; i <= n; i++){dist[i] = INF;}vis[s] = true;c[s]++;dist[s] = 0;qu.push(s);while (!qu.empty()){u = qu.front();qu.pop();vis[u] = false;for (int i = V[u].first; i != -1; i = E[i].next){v = E[i].v; if (E[i].cap > E[i].flow && dist[v] > dist[u] + E[i].cost){ dist[v] = dist[u] + E[i].cost;pre[v] = i;if (!vis[v]){ c[v]++;qu.push(v); vis[v] = true;if (c[v] > n){ return false;}}}}}cout << "最短可增流路径数组:\n";cout << "dist[]=>";for (int i = 1; i <= n; i++){cout << " " << dist[i];}cout << "\n";if (dist[t] == INF){ return false;}return true;
}void print(int s, int t)
{cout<<"s->t:"<<s<<" "<<t<<" "; int v;vis[s] = 1;for (int i = V[s].first; ~i; i = E[i].next){ v = E[i].v;if (!vis[v] && ((E[i].flow > 0 && E[i].cost <= 0) || (E[i].flow < 0 && E[i].cost >= 0))){print(v, t);if (v <= t){cout << str[v] << endl;}}}
}