HDU 3062 && HDU 1824 && POJ 3578 && BZOJ 1997 2-SAT

一条边<u,v>表示u选那么v一定被选。

 1 #include <iostream>
 2 #include <cstring>
 3 #include <cstdio>
 4 #include <algorithm>
 5 using namespace std;
 6 const int Maxm=21000;
 7 const int Maxn=2010;
 8 struct EDGE{int to,next;}edge[Maxm];
 9 int T,m,Stack[Maxn],head[Maxn],Belong[Maxn],Id[Maxn],Dfn[Maxn],Low[Maxn],h1,h2,h,Stamp,scc,top,cnt;
10 bool vis[Maxn];
11 inline int Min(int x,int y) {return x>y?y:x;}
12 inline void Add(int u,int v){edge[cnt].to=v;edge[cnt].next=head[u];head[u]=cnt++;}
13 inline bool Check()
14 {
15     for (int i=0;i<T;i++) if (Belong[i<<1]==Belong[i<<1|1]) return false;
16     return true;
17 }
18 void Tarjan(int u)
19 {
20     Stack[++top]=u; vis[u]=true;
21     Low[u]=Dfn[u]=++Stamp;
22     for (int i=head[u];i!=-1;i=edge[i].next)
23         if (Dfn[edge[i].to]==-1) Tarjan(edge[i].to),Low[u]=Min(Low[u],Low[edge[i].to]); else
24         if (vis[edge[i].to]) Low[u]=Min(Low[u],Dfn[edge[i].to]);
25     if (Dfn[u]==Low[u])
26     {
27         while (true)
28         {
29             int v=Stack[top--];
30             Belong[v]=scc;
31             vis[v]=false;
32             if (u==v) break;
33         }
34         scc++;
35     }
36 }
37
38 int main()
39 {
40
41     while (scanf("%d%d",&T,&m)!=EOF)
42     {
43         for (int i=0;i<T;i++)
44         {
45             scanf("%d%d%d",&h,&h1,&h2);
46             Id[h]=i<<1;
47             Id[h1]=Id[h2]=i<<1|1;
48         }
49         memset(head,-1,sizeof(head));
50         memset(Dfn,-1,sizeof(Dfn));
51         cnt=Stamp=top=0;
52         for (int i=1;i<=m;i++)
53         {
54             scanf("%d%d",&h1,&h2);
55             Add(Id[h1],Id[h2]^1),Add(Id[h2],Id[h1]^1);
56         }
57
58         for (int i=0;i<T*2;i++) if (Dfn[i]==-1) Tarjan(i);
59         puts(Check()?"yes":"no");
60     }
61     return 0;
62 }

HDU 1824

 1 #include <iostream>
 2 #include <cstring>
 3 #include <cstdio>
 4 #include <algorithm>
 5 using namespace std;
 6 const int Maxm=1000100;
 7 const int Maxn=2010;
 8 struct EDGE{int to,next;}edge[Maxm];
 9 int head[Maxn],Dfn[Maxn],Low[Maxn],Belong[Maxn],scc,Stk[Maxn],top,cnt,Stamp,n,m;
10 int p1,p2,c1,c2;
11 bool vis[Maxn];
12 inline int Min(int x,int y) {return x>y?y:x;}
13 inline int Id(int num,int pos){return (num<<1)+pos+1;}
14 inline void Add(int u,int v) {edge[cnt].to=v;edge[cnt].next=head[u];head[u]=cnt++;}
15 inline bool Check()
16 {
17     for (int i=0;i<n;i++) if (Belong[Id(i,0)]==Belong[Id(i,1)]) return false;
18     return true;
19 }
20 void Tarjan(int u)
21 {
22     Stk[++top]=u; vis[u]=true;
23     Dfn[u]=Low[u]=++Stamp;
24     for (int i=head[u];i!=-1;i=edge[i].next)
25         if (Dfn[edge[i].to]==-1) Tarjan(edge[i].to),Low[u]=Min(Low[u],Low[edge[i].to]); else
26         if (vis[edge[i].to]) Low[u]=Min(Low[u],Dfn[edge[i].to]);
27     if (Low[u]==Dfn[u])
28     {
29         while (true)
30         {
31             int v=Stk[top--];
32             vis[v]=false;
33             Belong[v]=scc;
34             if (v==u) break;
35         }
36         scc++;
37     }
38 }
39 int main()
40 {
41     while (scanf("%d%d",&n,&m)!=EOF)
42     {
43         memset(head,-1,sizeof(head));
44         memset(Dfn,-1,sizeof(Dfn));
45         memset(Belong,0,sizeof(Belong));
46         cnt=top=scc=0;
47         for (int i=1;i<=m;i++)
48         {
49             scanf("%d%d%d%d",&p1,&p2,&c1,&c2);
50             Add(Id(p1,c1),Id(p2,1-c2)),Add(Id(p2,c2),Id(p1,1-c1));
51         }
52         for (int i=1;i<=2*n;i++) if (Dfn[i]==-1) Tarjan(i);
53         puts(Check()?"YES":"NO");
54     }
55     return 0;
56 }

HDU 3062

 1 #include <iostream>
 2 #include <cstring>
 3 #include <cstdio>
 4 #include <algorithm>
 5 using namespace std;
 6 const int Maxn=2010;
 7 const int Maxm=4010000;
 8 int One[Maxn],Zero[Maxn],Stack[Maxn],Belong[Maxn],head[Maxn],Low[Maxn],Dfn[Maxn],n,m,u,v,w,cnt,Stamp,scc,top;
 9 bool vis[Maxn];
10 char ch[20];
11 struct EDGE{int to,next;}edge[Maxm];
12 inline int Min(int x,int y){return x>y?y:x;}
13 inline void Add(int u,int v){edge[cnt].to=v;edge[cnt].next=head[u];head[u]=cnt++;}
14 inline bool Check()
15 {
16     for (int i=0;i<n;i++) if (Belong[One[i]]==Belong[Zero[i]]) return false;
17     return true;
18 }
19 void Tarjan(int u)
20 {
21     Stack[++top]=u; vis[u]=true;
22     Low[u]=Dfn[u]=++Stamp;
23     for (int i=head[u];i!=-1;i=edge[i].next)
24         if (Dfn[edge[i].to]==-1) Tarjan(edge[i].to),Low[u]=Min(Low[u],Low[edge[i].to]); else
25         if (vis[edge[i].to]) Low[u]=Min(Low[u],Dfn[edge[i].to]);
26     if (Low[u]==Dfn[u])
27     {
28         while (true)
29         {
30             int v=Stack[top--];
31             vis[v]=false;
32             Belong[v]=scc;
33             if (u==v) break;
34         }
35         scc++;
36     }
37 }
38 int main()
39 {
40     scanf("%d%d",&n,&m);
41     for (int i=0;i<n;i++) One[i]=i<<1,Zero[i]=i<<1|1;
42     memset(head,-1,sizeof(head));
43     memset(Dfn,-1,sizeof(Dfn));
44     for (int i=1;i<=m;i++)
45     {
46         scanf("%d%d%d%s",&u,&v,&w,ch);
47         if (ch[0]==‘A‘)
48         {
49             if (w==1) Add(Zero[u],One[u]),Add(Zero[v],One[v]);
50             if (w==0) Add(One[u],Zero[v]),Add(One[v],Zero[u]);
51         }
52         if (ch[0]==‘O‘)
53         {
54             if (w==1) Add(Zero[u],One[v]),Add(Zero[v],One[u]);
55             if (w==0) Add(One[v],Zero[v]),Add(One[u],Zero[u]);
56         }
57         if (ch[0]==‘X‘)
58         {
59             if (w==1) Add(One[u],Zero[v]),Add(Zero[u],One[v]),Add(Zero[v],One[u]),Add(One[v],Zero[u]);
60             if (w==0) Add(One[u],One[v]),Add(One[v],One[u]),Add(Zero[u],Zero[v]),Add(Zero[v],Zero[u]);
61         }
62     }
63
64     for (int i=0;i<n<<1;i++) if (Dfn[i]==-1) Tarjan(i);
65     puts(Check()?"YES":"NO");
66     return 0;
67 }

POJ 3578

 1 #include <cstdio>
 2 #include <iostream>
 3 #include <cstring>
 4 #include <algorithm>
 5 using namespace std;
 6 const int Maxm=80100;
 7 int Stk[Maxm],Low[Maxm],Dfn[Maxm],head[Maxm],Belong[Maxm],In[Maxm],Out[Maxm],Pos[Maxm];
 8 int cnt,top,Stamp,KASE,scc,n,m,x,u[Maxm],v[Maxm],tot;
 9 bool vis[Maxm];
10 struct EDGE{int to,next;}edge[Maxm<<4];
11 inline int Min(int x,int y) {return x>y?y:x;}
12 inline void Swap(int &x,int &y) {int t=x;x=y;y=t;}
13 inline void Add(int u,int v) {edge[cnt].to=v;edge[cnt].next=head[u];head[u]=cnt++;}
14 inline bool Check()
15 {
16     for (int i=1;i<=m;i++) if (Belong[In[i]]==Belong[Out[i]]) return false;
17     return true;
18 }
19 void Tarjan(int u)
20 {
21     Stk[++top]=u; vis[u]=true;
22     Low[u]=Dfn[u]=++Stamp;
23     for (int i=head[u];i!=-1;i=edge[i].next)
24         if (Dfn[edge[i].to]==-1) Tarjan(edge[i].to),Low[u]=Min(Low[u],Low[edge[i].to]); else
25         if (vis[edge[i].to]) Low[u]=Min(Low[u],Dfn[edge[i].to]);
26     if (Low[u]==Dfn[u])
27     {
28         while (true)
29         {
30             int v=Stk[top--];
31             vis[v]=false;
32             Belong[v]=scc;
33             if (u==v) break;
34         }
35         scc++;
36     }
37 }
38 int main()
39 {
40     scanf("%d",&KASE);
41     for (int Kase=1;Kase<=KASE;Kase++)
42     {
43         scanf("%d%d",&n,&m);
44         for (int i=1;i<=m;i++) scanf("%d%d",&u[i],&v[i]);
45         for (int i=1;i<=n;i++) scanf("%d",&x),Pos[x]=i;
46         if(m>3*n-6){puts("NO");continue;}
47         for (int i=0;i<m;i++) In[i+1]=i<<1,Out[i+1]=i<<1|1;
48         tot=0;
49         for (int i=1;i<=m;i++)
50         {
51             u[i]=Pos[u[i]],v[i]=Pos[v[i]];
52             if (v[i]<u[i]) Swap(u[i],v[i]);
53             if ((v[i]-u[i]==1) || (v[i]==n && u[i]==1)) continue;
54             u[++tot]=u[i],v[tot]=v[i];
55         }
56         m=tot;
57         memset(Dfn,-1,sizeof(Dfn));
58         memset(head,-1,sizeof(head));
59         memset(vis,false,sizeof(vis));
60         Stamp=cnt=top=scc=0;
61
62         for (int i=1;i<=m;i++)
63             for (int j=i+1;j<=m;j++)
64                 if (((u[i]<u[j] && u[j]<v[i] && v[i]<v[j]) || (u[j]<u[i] && u[i]<v[j] && v[j]<v[i])))
65                     Add(In[i],Out[j]),Add(In[j],Out[i]),Add(Out[i],In[j]),Add(Out[j],In[i]);
66
67         for (int i=0;i<m<<1;i++) if (Dfn[i]==-1) Tarjan(i);
68         puts(Check()?"YES":"NO");
69     }
70     return 0;
71 }
72 

BZOJ 1997

时间: 2024-10-25 11:30:32

HDU 3062 && HDU 1824 && POJ 3578 && BZOJ 1997 2-SAT的相关文章

HDU 3062 Party (2-sat)

题目地址:HDU 3062 2-sat第一发.水题.. 首先假设A,A'为同一组的两个布尔变量且不能同时选择同一组的两个变量.如果存在一种同时选择了A和A'的方案,则该方案无解. 设<X,Y>为选择X就必须选择Y,则基本的建图如下: A,B不能同时选:<A,B'><B,A'>,表示选择A就必须不能选择B,选择B就不能选择A A,B不能同时不选:<A',B><B',A>,表示不选A则必须选B,不选B则必须选A A,B必须同时选或同时不选:<A

HDU 3062

http://acm.hdu.edu.cn/showproblem.php?pid=3062 2sat判定性问题模板 #include <iostream> #include <algorithm> #include <cstring> #include <cstdio> #include <queue> #include <map> using namespace std ; struct node { int s,t,nxt ;

HDU 3062 简单的2-SAT问题

在2-SAT,最让我纠结的还是添加有向线段的函数了 void add_clause(int i,int a,int j,int b){    int m=2*i+a;    int n=2*j+b;    G[m^1].push_back(n);    G[n^1].push_back(m);} 这里a,b因为只有真假两种情况,所以只取0或1,这里表示m V n是正确的,那么意思是取到m^1时,那么n必然得取到 同理取到n^1时,m必然取到,所以两条有向线段就添加成功了 例如这道题给所有夫妻排好

hdu 3061 hdu 3996 最大权闭合图 最后一斩

hdu 3061 Battle :一看就是明显的最大权闭合图了,水提......SB题也不说边数多少....因为开始时候数组开小了,WA....后来一气之下,开到100W,A了.. hdu3996.  gold mine..看了一下,简单题,几乎裸,不敲了.. #include<iostream>//Battle #include<queue> #include<cstdio> #include<cstring> #include<set> #i

hdu 3081 hdu 3277 hdu 3416 Marriage Match II III IV //最大流的灵活运用

3081 题意: n个女孩选择没有与自己吵过架的男孩有连边(自己的朋友也算,并查集处理),2分图,有些边,求有几种完美匹配(每次匹配每个点都不重复匹配) 我是建二分图后,每次增广一单位,(一次完美匹配),再修改起点还有终点的边流量,继续增广,直到达不到完美匹配为止.网上很多是用二分做的,我觉得没必要...(网上传播跟风真严重...很多人都不是真正懂最大流算法的...) 3277 : 再附加一条件,每个女孩可以最多与k个自己不喜欢的男孩.求有几种完美匹配(同上). 我觉得:求出上题答案,直接ans

2014多校联合六(HDU 4923 HDU 4925 HDU 4927 HDU 4930)

HDU 4923 Room and Moor 题意:给出A序列  求满足题目所写的B序列  使得方差最小 思路:可以想到最后的结果中  B序列的值一定是一段一段的  那么我们可以类似贪心去搞  对于一段序列我们可以求出什么样的b值使得方差最小  即序列中1的个数除以序列长度  又因为B是单调的  可以用一个单调栈去模拟  复杂度远远小于n^2  不要被吓怕- 代码: #include<cstdio> #include<cstring> #include<algorithm&g

2014多校联合三 (HDU 4888 HDU 4891 HDU 4893)

HDU 4891 The Great Pan 签到题  他怎么说你就怎么做就好了  注意做乘法时候会爆int 代码: #include<iostream> #include<cstdio> #include<cstring> #include<algorithm> using namespace std; typedef long long LL; int n; char s[2000000]; int flag1, flag2, sp, ansflag;

SG 函数初步 HDU 1536 &amp;&amp; HDU 1944

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1944 http://acm.hdu.edu.cn/showproblem.php?pid=1536 给定每一次可以取的石头数,给定很多种情况,每一种情况有若干堆石头,判断先手胜负. SG函数打表,然后直接抑或,判断结果是否为0,第一次写SG函数,贴个代码,慢慢理解. 代码: /* *********************************************** Author :rabb

hdu 3879 hdu 3917 构造最大权闭合图 俩经典题

hdu3879  base station : 各一个无向图,点的权是负的,边的权是正的.自己建一个子图,使得获利最大. 一看,就感觉按最大密度子图的构想:选了边那么连接的俩端点必需选,于是就以边做点,轻轻松松构造了最大权闭合图.简单题.分分钟搞定. hdu3917 :road  constructions :这题题目看了半天没理解...感觉描述的不好...一个有向图,每条路有响应公司承保,若选了该公司,那么该公司的路必需全部选,还有,该公司的承保的路的下面的一条路对应公司也要选,求最大获利.构