zoj 3448(最大流)

#include <utility>
#include <algorithm>
#include <string>
#include <cstring>
#include <cstdio>
#include <iostream>
#include <iomanip>
#include <set>
#include <vector>
#include <cmath>
#include <queue>
#include <bitset>
#include <map>
#include <iterator>
#include <numeric>
using namespace std;
#define clr(a,v) memset(a,v,sizeof(a))
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
const int INF = 0x7f7f7f7f;
const int maxn = 1111;
const double pi = acos(-1.0);
const double eps = 1e-10;
const int mod = 777777777;
typedef long long LL;
typedef unsigned long long ULL;
typedef pair<int, int> pii;
typedef vector<int> VI;
typedef vector<VI> VVI;
typedef vector<VVI> VVVI;
const int N = 1111;
const int M = 111111;
struct Edge
{
	int v,c,next;
}edge[M];
int E,head[N],cur[N],dis[N],gap[N],pre[N];
void add_edge(int s,int t,int c,int cc=0)
{
	edge[E].v=t;
	edge[E].c=c;
	edge[E].next=head[s];
	head[s]=E++;
	edge[E].v=s;
	edge[E].c=cc;
	edge[E].next=head[t];
	head[t]=E++;
}
inline int min(int a,int b) { return (a==-1||b<a)?b:a;}
int sap(int s,int t,int n)
{
	memset(gap,0,sizeof(gap));
	memset(dis,0,sizeof(dis));
	int i;
	for(i=0;i<=n;i++) cur[i]=head[i];
	int u=pre[s]=s,maxflow=0,aug=-1,v;
	gap[0]=n;
	while(dis[s]<n)
	{
loop:for(i=cur[u];~i;i=edge[i].next)
	 {
		 v=edge[i].v;
		 if(edge[i].c>0&&dis[u]==dis[v]+1)
		 {
			 aug=min(aug,edge[i].c);
			 cur[u]=i;
			 pre[v]=u;
			 u=v;
			 if(u==t)
			 {
				 for(u=pre[u];v!=s;v=u,u=pre[u])
				 {
					 edge[cur[u]].c-=aug;
					 edge[cur[u]^1].c+=aug;
				 }
				 maxflow+=aug;
				 aug=-1;
			 }
			 goto loop;
		 }
	 }
	 int mindis=n;
	 for(i=head[u];~i;i=edge[i].next)
	 {
		 v=edge[i].v;
		 if(edge[i].c>0&&dis[v]<mindis)
		 {
			 mindis=dis[v];
			 cur[u]=i;
		 }
	 }
	 if((--gap[dis[u]])==0) break;
	 gap[dis[u]=mindis+1]++;
	 u=pre[u];
	}
	return maxflow;
}
string a, b, c;
int win[maxn];
int remain[maxn];
int game[111][111];
pair<int, int> p[maxn];
bool go(int P, int tot, int n) {
	int i, u, v;
	E = 0;
	int s = 0, t = n + 1,j;
	memset(head, -1, sizeof(head));
	for (i = 1; i <=n; ++i) {
		add_edge(s,i,win[i]);
		add_edge(i,t,tot-1);
		for(j=i+1;j<=n;++j)
		{
            if(game[i][j])
             add_edge(i,j,game[i][j]);
        }
	}
	int tmp=accumulate(win+1,win+n+1,0);
	int flow = sap(s, t, t + 1);
	return flow == tmp;
}
int main() {
	ios::sync_with_stdio(false);
	int n, m, P, u, v, i, cnt;
	while (cin >> n >> m) {
		memset(win, 0, sizeof(win));
		memset(game,0,sizeof(game));
		cnt = 0;
		map<string, int> mp;
		mp["DD"]=0;
		for (i = 0; i < m; ++i) {
			cin >> a >> b >> c;
			if (!mp.count(a))
				mp[a] = ++cnt;
			if (!mp.count(b))
				mp[b] = ++cnt;
			u = mp[a];
			v = mp[b];
			if (c == "win")
				win[u]++;
			else
				win[v]++;
		}
		cin >> P;
		for (i = 1; i <= P; ++i) {
			cin >> a >> b;
			if(!mp.count(a))
			   mp[a]=++cnt;
            if(!mp.count(b))
               mp[b]=++cnt;
			u = mp[a];
			v = mp[b];
			if(u>v) swap(u,v);
			win[u]++;
			game[u][v]++;
		}
        if(n==1)
		  cout<<"Yes"<<endl;
		else if (go(P, win[0], cnt))
			cout << "Yes" << endl;
		else
			cout << "No" << endl;
	}
	return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值