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;
}