图论 day 4 差分约束系统 2-sat

poj 3678 2-sat 跑tarjan缩点

附上代码

#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>

using namespace std;

const int maxn=2010;

int n,m,tot=0,idx=0,top=0,cnt=0;

int color[maxn],dfn[maxn],low[maxn],stk[maxn*10];

bool vis[maxn];

int head[maxn*maxn],tov[maxn*maxn],nxt[maxn*maxn];

void add(int u,int v)
{
	tot++;
	tov[tot]=v;
	nxt[tot]=head[u];
	head[u]=tot;
}

void add(int u,int v,int z,string s)
{
	if (s[0]=='A')
	{
		if (z==1)
		{
			add(u+n,v);
			add(v+n,u);
			add(u,v);
			add(v,u);
		}
		else
		{
			add(u,v+n);
			add(v,u+n);
		}
	}
	if (s[0]=='O')
	{
		if (z==1)
	    {
	    	add(u+n,v);
	    	add(v+n,u);
	    }
	    else
	    {
	    	add(u+n,v+n);
	    	add(v+n,u+n);
	    	add(v,v+n);
	    	add(u,u+n);
	    }
	}
	if (s[0]=='X')
	{
		if (z==1)
		{
			add(u,v+n);
			add(v,u+n);
			add(v+n,u);
			add(u+n,v);
		}
		else
		{
			add(u,v);
			add(v,u);
			add(u+n,v+n);
			add(v+n,u+n);
		}
	}
}

void tarjan(int u)
{
	idx++;
	low[u]=dfn[u]=idx;
	stk[++top]=u;
	vis[u]=1;
	for (int i=head[u];i;i=nxt[i])
	{
		int v=tov[i];
		if (!dfn[v])
		{
			tarjan(v);
		low[u]=min(low[u],low[v]);
		}
		else if (vis[v])
		low[u]=min(dfn[v],low[u]);   
	}
	if (low[u]==dfn[u])
	{
		cnt++;
		while (1)
		{
			int x=stk[top--];
			vis[x]=0;
			color[x]=cnt;
			if (u==x)
			    break;
		}
	}
}

int main()
{
	bool pd=1;
	scanf("%d%d",&n,&m);
	for (int i=1;i<=m;i++)
	{
		int a,b,c;
		char s[10];
		scanf("%d%d%d%s",&a,&b,&c,s);
		add(a,b,c,s);
	}
	for (int i=1;i<=n*2;i++)
	   if (!dfn[i])
	      tarjan(i);
	for (int i=0;i<=n;i++)
	   if (color[i]==color[i+n])
	      {
	      	pd=0;
	      	break;
	      }
	if (pd)
	printf("YES\n");
	else
	printf("NO");
}

poj 1201 差分约束区间 【a,b】用sum【b】-sum【a-1】表示,相邻两个加上大于等于0小于等于1的限制跑spfa

#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>

using namespace std;

const int maxn=150005;

const int Inf=1e8;

int n,st=1e8,en=-1e8,tot=0;

struct edge
{
	int nxt,tov,f;
}e[maxn];

int h[maxn],dis[maxn],q[maxn*5];

bool vis[maxn];

void add(int u,int v,int f)
{
	tot++;
	e[tot].tov=v;
	e[tot].nxt=h[u];
	e[tot].f=f;
	h[u]=tot;
}

int spfa()
{
	int head=0,tail=1;
	memset(vis,0,sizeof(vis));
	memset(dis,128,sizeof(dis));
	vis[st]=1;
	dis[st]=0;
	q[tail]=st;
	while (head<tail)
	{
		int u=q[++head];
		for (int i=h[u];i!=0;i=e[i].nxt)
		{
			int v=e[i].tov;
			if (dis[v]<dis[u]+e[i].f)
			{
				dis[v]=dis[u]+e[i].f;
				if (!vis[v])
				{
					vis[v]=1;
					q[++tail]=v;
				}
			}
		}
		vis[u]=0;
	}
	return dis[en];
}

int main()
{
	scanf("%d",&n);
	for (int i=1;i<=n;i++)
	{
		int a,b,c;
		scanf("%d%d%d",&a,&b,&c);
		if (a<st)
		   st=a;
		if (b>en)
		   en=b;
		if (a==0)
		add(a,b,c);
		else
		add(a-1,b,c);
	}
	st-=1;
	for (int i=st+1;i<=en;i++)
	{
		add(i-1,i,0);
		add(i,i-1,-1);
	}
	printf("%d\n",spfa());
    return 0;
}

洛谷3254 圆桌问题

网络流24题 二分图最大匹配

加上hh【i】=h【i】和&&delta优化后跑的贼快

附上代码

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int n,m,huan,hui;
int tp=1,nex[100005],hh[100005],h[100005],tov[100005],tow[100005],a[1005][1005];
int q[10005],dis[10005],vis[10005],head,tail;
int r[10005],w[10005];
void add(int x,int y,int w)
{
    tp++;
    tov[tp]=y;
    tow[tp]=w;
    nex[tp]=h[x];
    h[x]=tp;
    tp++;
    tov[tp]=x;
    tow[tp]=0;
    nex[tp]=h[y];
    h[y]=tp;
}
bool bfs()
{
    memset(dis,0,sizeof(dis));
    memset(q,0,sizeof(q));
    memset(vis,0,sizeof(vis));
    head=0;tail=1;
    q[tail]=huan;
    vis[huan]=1;
    while(head<tail)
    { 
    head++;
    int x=q[head];
    for(int i=h[x];i;i=nex[i])
    {
          int v=tov[i];
          if(tow[i]!=0&&vis[v]==0)
          {
          	dis[v]=dis[x]+1;
          	vis[v]=1;
          	tail++;
          	q[tail]=v;
          	hh[x]=i;
          }
    }
    }
   return vis[hui];
}
int dfs(int x,int delta)
{
    if(x==hui)
    return delta;
    int rest=0;
    for(int i=hh[x];i&δi=nex[i])
    {
          int v=tov[i];
          if(tow[i]!=0&&dis[v]==dis[x]+1)
          {
         int dd=dfs(v,min(delta,tow[i]));
          	rest+=dd;
          	tow[i]-=dd;
          	tow[i^1]+=dd;
            delta-=dd;
            if(tow[i]==0)a[x][v]=1;
            else a[x][v] = 0;
            if(tow[i^1]==0)a[v][x]=1;
            else a[v][x] = 0;
            hh[x]=i;
          }
    }
    return rest;
}
int main()
{
    cin>>m>>n;
    int s=0;
    for(int i=1;i<=m;i++)
    {
        cin>>r[i];s+=r[i];
    }
    for(int i=1;i<=n;i++)
    {
        cin>>w[i];
    }
    for(int i=1;i<=m;i++)
    {
        add(0,i,r[i]);
    }
    for(int i=1;i<=m;i++)
      for(int j=1;j<=n;j++)
      	{
      		add(i,j+m,1);
      	}
    for(int j=1;j<=n;j++)
     add(j+m,1+m+n,w[j]);
      int ans=0,inf=1e8;
      huan=0;
      hui=n+m+1;
    while(bfs())
    { 
    for (int i=0;i<=m+n+1;i++)
       hh[i]=h[i];
    ans+=dfs(huan,inf);
    }
    if(ans==s)
         {
         	cout<<"1"<<endl;
         	for(int i=1;i<=m;i++)
         	{
             for(int j=m+1;j<=n+m;j++)
         	if(a[i][j]==1) printf("%d ",j-m);
         	cout<<endl;
            }
         }
         else printf("0\n");
    return 0;
}

猜你喜欢

转载自blog.csdn.net/beloved_rancy/article/details/79365653
今日推荐