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