旅游路线问题
#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;
}
}
}
}
|