刚开始看这题太长了就放着,后来做了之后才发现并不难,就是构造图有点麻烦
一开始写了180行@。@结果tle了,后来想到用map直接访问的话可能会快点,就不用每次循环了
#include<map> #include<set> #include<cmath> #include<queue> #include<stack> #include<vector> #include<cstdio> #include<iomanip> #include<cstdlib> #include<cstring> #include<iostream> #include<algorithm> #define pi acos(-1) #define ll long long #define mod 100000000 #define ls l,m,rt<<1 #define rs m+1,r,rt<<1|1 #define MIN(a,b) a<b ? a:b using namespace std; const double g=10.0,eps=1e-9; const int N=100000+10,maxn=500+10,inf=1000000; struct edge{ int to,next,cap; }e[N<<2]; int cnt,s,t; int dis[N],head[N]; void add(int u,int v,int c) { e[cnt].to=v; e[cnt].cap=c; e[cnt].next=head[u]; head[u]=cnt++; e[cnt].to=u; e[cnt].cap=0; e[cnt].next=head[v]; head[v]=cnt++; } bool bfs() { queue<int>q; q.push(s); memset(dis,-1,sizeof dis); dis[s]=0; while(!q.empty()){ int x=q.front(); q.pop(); for(int i=head[x];i!=-1;i=e[i].next) { int p=e[i].to; if(dis[p]==-1&&e[i].cap>0) { // cout<<p<<endl; dis[p]=dis[x]+1; q.push(p); } } } return dis[t]>-1; } int dfs(int x,int mx) { if(x==t)return mx; for(int i=head[x];i!=-1;i=e[i].next) { int p=e[i].to,f; if(dis[p]==dis[x]+1&&e[i].cap>0&&(f=dfs(p,min(mx,e[i].cap)))) { e[i].cap-=f; e[i^1].cap+=f; return f; } } dis[x]=-2; return 0; } int max_flow() { int flow=0,f; while(bfs()){ while(f=dfs(s,inf)){ // cout<<f<<endl; flow+=f; } } return flow; } int main() { ios::sync_with_stdio(false); cin.tie(0); int n,m,k=0; map<string,int>ma; while(cin>>n){ int cnt=0; memset(head,-1,sizeof head); string na1,na2; for(int i=1;i<=n;i++) { cin>>na1; ma[na1]=i; add(i,i+n,1); } cin>>m; for(int i=1;i<=m;i++) { cin>>na1>>na2; add(0,2*n+i,inf); int p=ma[na2]; if(p==0) { ++k; ma[na2]=2*n+m+k; add(2*n+i,2*n+m+k,1); } else add(2*n+i,p,1); } cin>>s; while(s--){ cin>>na1>>na2; int p1=ma[na1],p2=ma[na2]; add(p1,p2,inf); } for(int i=1;i<=n;i++)add(n+i,2*n+m+k+1,inf); s=0,t=2*n+m+k+1; int ans=max_flow(); cout<<m-ans<<endl; } return 0; }