看了题解后:确实不难

开 始 一 直 有 个 小 问 题 , 怎 么 表 示 从 1 到 n 再 回 到 1 开始一直有个小问题,怎么表示从1到n再回到1 ,1n1

实际上等价于1到n的两条不同路径

这 样 就 发 现 可 以 把 1 看 成 源 点 , n 看 成 汇 点 , 构 建 一 条 2 为 最 大 流 的 网 络 这样就发现可以把1看成源点,n看成汇点,构建一条2为最大流的网络 1,n,2

又 突 然 发 现 每 条 边 每 个 点 只 能 走 一 次 , 当 然 1 和 n 可 以 走 两 次 又突然发现每条边每个点只能走一次,当然1和n可以走两次 ,1n

那 就 把 一 个 点 拆 成 两 个 点 , 两 个 点 一 个 负 责 连 入 的 边 , 一 个 负 责 连 出 那就把一个点拆成两个点,两个点一个负责连入的边,一个负责连出 ,,

两 个 点 间 用 流 量 为 1 的 边 来 限 制 只 能 走 一 次 , 费 用 用 1 代 表 选 了 这 个 节 点 两个点间用流量为1的边来限制只能走一次,费用用1代表选了这个节点 1,1

然 后 跑 裸 的 最 大 费 用 最 大 流 然后跑裸的最大费用最大流

输 出 方 案 每 条 路 径 用 一 次 d f s 即 可 输出方案每条路径用一次dfs即可 dfs

#include <bits/stdc++.h>
using namespace std;
const int inf=1e9;
map<string,int>mp;
map<int,string>cp;
const int maxn=2e5+20;
struct edge{
	int to,w,flow,nxt;
}d[maxn]; int head[maxn],cnt=1;
void add(int u,int v,int flow,int w){
	d[++cnt]=(edge){v,w,flow,head[u]},head[u]=cnt;
	d[++cnt]=(edge){u,-w,0,head[v]},head[v]=cnt;
}
int n,m,s,t;
int dis[maxn],vis[maxn],maxflow,maxcost,flow[maxn],pre[maxn];
bool spfa()
{
	queue<int>q;
	for(int i=0;i<=t;i++)	dis[i]=-inf;
	q.push( s ); dis[s]=0;flow[s]=inf;
	while( !q.empty() )
	{
		int u=q.front(); q.pop();
		vis[u]=0;
		for(int i=head[u];i;i=d[i].nxt )
		{
			int v=d[i].to;
			if( d[i].flow&&dis[v]<dis[u]+d[i].w )
			{
				dis[v]=dis[u]+d[i].w;
				flow[v]=min( flow[u],d[i].flow );
				pre[v]=i;
				if( !vis[v] )	vis[v]=1,q.push( v );
			}
		}
	}
	if( dis[t]==-inf )	return false;
	return true;
}
void dinic()
{
	while( spfa() )
	{
		int x=t;
		maxflow+=flow[t],maxcost+=flow[t]*dis[t];
		while( x!=s )
		{
			int i=pre[x];
			d[i].flow-=flow[t];
			d[i^1].flow+=flow[t];
			x=d[i^1].to;
		}
	}
}
void dfs1(int x)
{
	vis[x]=1;//表示经过了此节点
	cout << cp[x-n] << endl;
	for(int i=head[x];i;i=d[i].nxt )
		if( d[i].to<=n&&!d[i].flow )
		{
			dfs1(d[i].to+n);
			break;
		}
}
void dfs2(int x)
{
	for(int i=head[x];i;i=d[i].nxt )
		if( d[i].to<=n&&!d[i].flow&&!vis[d[i].to+n] )
		{
			dfs2(d[i].to+n);
			break;
		}
	cout << cp[x-n] << endl;
}
int main()
{
	cin >> n >> m;
	for(int i=1;i<=n;i++)
	{
		string kk; cin >> kk;
		mp[kk]=i,cp[i]=kk;
		if( i==1 )	add(1,1+n,2,1);
		else if( i==n )	add(n,n+n,2,1);
		else	add(i,i+n,1,1);
	}
	int flag=0;
	for(int i=1;i<=m;i++)
	{
		string q,w; cin >> q >> w;
		int l=mp[q],r=mp[w];
		if( l==1&&r==n )	flag=1;
		if( l==n&&r==1 )	flag=1;
		add(l+n,r,1,0);
	}
	s=1,t=n+n;
	dinic();
	if( maxflow==2 )
	{
		cout << maxcost-2 << endl;
		dfs1(1+n);
		dfs2(1+n);
	}
	else if( maxflow==1&&flag )	
		cout << 2 << "\n" << cp[1] << "\n" << cp[n] << "\n" << cp[1];
	else	cout << "No Solution!\n";  
}