只需要把费用流的Spfa中的小于号改一下就好了,对于题目中要求要飞过去在飞回来,只需要一律把边的方向定为从顶点编号较小的向顶点编号较大的,把顶点1和n的边的容量定为2,其余边为1即可。
#include <iostream> #include <algorithm> #include <cstdio> #include <cstdlib> #include <cstring> #include <cmath> #include <ctime> #include <map> #include <string> #include <queue> using namespace std; template<const int _n,const int _m> struct Edge { struct Edge_base { int to,next,w,c; }e[_m]; int cnt,p[_n]; Edge() { clear(); } int start(const int x) { return p[x]; } void insert(const int x,const int y,const int z,const int zz) { e[++cnt].to=y; e[cnt].next=p[x]; e[cnt].w=z; e[cnt].c=zz; p[x]=cnt; return ; } void clear() { cnt=1,memset(p,0,sizeof(p)); } Edge_base& operator[](const int x) { return e[x]; } }; Edge<310,210000> e; map<string,int> Map; int n,m,Cost,SSS,TTT; int Dis[310],cur[310]; bool visited[310]; bool Spfa(const int S) { int i,t,temp; queue<int> Q; memset(Dis,0x80,sizeof(Dis)); memset(visited,0,sizeof(visited)); Dis[S]=0; visited[S]=true; Q.push(S); while(!Q.empty()) { t=Q.front(),Q.pop();visited[t]=false; for(i=e.start(t);i;i=e[i].next) { temp=e[i].to; if(Dis[temp]<Dis[t]+e[i].c && e[i].w) { Dis[temp]=Dis[t]+e[i].c; if(!visited[temp]) { Q.push(temp); visited[temp]=true; } } } } return Dis[TTT]!=(int)0x80808080; } int Dfs(const int S,const int bk) { if(S==TTT)return bk; int rest=bk; visited[S]=true; for(int &i=cur[S];i;i=e[i].next) { if(Dis[S]+e[i].c==Dis[e[i].to] && e[i].w && !visited[e[i].to]) { int flow=Dfs(e[i].to,min(rest,e[i].w)); Cost+=flow*e[i].c; e[i].w-=flow; e[i^1].w+=flow; if((rest-=flow)<=0)break; } } visited[S]=false; if(bk==rest)Dis[S]=0x3f3f3f3f; return bk-rest; } int Dinic() { int flow=0; while(Spfa(SSS)) { memcpy(cur,e.p,sizeof(cur)); flow+=Dfs(SSS,0x3f3f3f3f); } return Cost; } int main() { freopen("in","r",stdin); freopen("out","w",stdout); int i; string str,str1,str2; cin >> n >> m; SSS=n<<1|1,TTT=SSS+1; for(i=1;i<=n;++i) { cin >> str; Map[str]=i; e.insert(i+n,i,1,0); e.insert(i,i+n,0,0); } e.insert(SSS,1,2,0); e.insert(1,SSS,0,0); e.insert(n+n,TTT,2,0); e.insert(TTT,n+n,0,0); for(i=1;i<=m;++i) { cin >> str1 >> str2; int x=Map[str1],y=Map[str2]; if(x>y)swap(x,y); e.insert(x,y+n,x!=1?x!=n?1:2:2,1); e.insert(y+n,x,0,-1); } int temp=Dinic(); if(temp)cout << temp << endl; else cout << "No Solution!" << endl; return 0; }
时间: 2024-10-26 15:08:00