2-sat

Let's go home http://acm.hdu.edu.cn/showproblem.php?pid=1824

 

把队长看成  a 点  把两个队员看成同一个点  a‘ ,a的对称点, 也就是 非a。 这个是2sat的点。  然后再根据输入 a b  那么 a要和b的对称点连边

b要和a的对称点连边,因为题目中说的选了a  ,b就不选,那就是选a就必须选 非b ,就是b’ 。

精简版

  1 #include<cstdio>
  2 #include<cstring>
  3 #include<queue>
  4 #include<stack>
  5 #define mt(a,b) memset(a,b,sizeof(a))
  6 using namespace std;
  7 class TwoSat { ///2-sat判定,solve函数返回是否有解,i结点的对称结点i^为i+n,
  8     static const int ME=10010;///边的个数
  9     static const int MV=4010;///点的个数
 10     struct G {
 11         struct E {
 12             int u,v,next;
 13         } e[ME];
 14         int le,head[MV];
 15         void init() {
 16             le=0;
 17             mt(head,-1);
 18         }
 19         void add(int u,int v) {
 20             e[le].u=u;
 21             e[le].v=v;
 22             e[le].next=head[u];
 23             head[u]=le++;
 24         }
 25     } g;
 26     class Tarjan { ///有向图强连通分量缩点o(MV+ME)
 27         int Index,Bcnt,num[MV],belong[MV],dfn[MV],low[MV];
 28         bool instack[MV];
 29         stack<int> s;
 30         void tarjan(int u) {
 31             dfn[u]=low[u]=++Index;
 32             instack[u]=true;
 33             s.push(u);
 34             int v;
 35             for(int i=g.head[u]; ~i; i=g.e[i].next) {
 36                 v=g.e[i].v;
 37                 if(!dfn[v]) {
 38                     tarjan(v);
 39                     low[u]=min(low[u],low[v]);
 40                 } else if(instack[v]) {
 41                     low[u]=min(low[u],dfn[v]);
 42                 }
 43             }
 44             if(dfn[u]==low[u]) {
 45                 Bcnt++;
 46                 do {
 47                     v=s.top();
 48                     s.pop();
 49                     instack[v]=false;
 50                     belong[v]=Bcnt;
 51                     num[Bcnt]++;
 52                 } while(u!=v);
 53             }
 54         }
 55     public:
 56         G g;
 57         void init() {
 58             g.init();
 59             Index=Bcnt=0;
 60             mt(num,0);
 61             mt(dfn,0);
 62             mt(low,0);
 63             mt(instack,0);
 64             while(!s.empty()) s.pop();
 65         }
 66         void add(int u,int v) {
 67             g.add(u,v);
 68         }
 69         void solve(int n) {///传入点数,点下标1开始
 70             for(int i=1; i<=n; i++) {
 71                 if(!dfn[i]) {
 72                     tarjan(i);
 73                 }
 74             }
 75         }
 76         int getbcnt() {///强连通分量的个数
 77             return Bcnt;
 78         }
 79         int getbelong(int id) {///属于哪个分量,分量下标1开始
 80             return belong[id];
 81         }
 82         int getnum(int id) {///某个分量的点的个数
 83             return num[id];
 84         }
 85     } T;
 86     int n;
 87 public:
 88     void init(int tn) { ///传入判定结点2*n
 89         n=tn;
 90         T.init();
 91     }
 92     void add(int u,int v) { ///如果取u必须取v结点添加边u->v,下标1开始
 93         T.add(u,v);
 94     }
 95     bool solve() {
 96         T.solve(n);
 97         for(int i=1,z=n/2; i<=z; i++) {
 98             if(T.getbelong(i)==T.getbelong(i+z))return false;
 99         }
100         return true;
101     }
102 } gx;
103 int mp[3010];
104 int main(){
105     int n,m,a,b,c;
106     while(~scanf("%d%d",&n,&m)){
107         for(int i=1;i<=n;i++){
108             scanf("%d%d%d",&a,&b,&c);
109             mp[a]=i;
110             mp[b]=mp[c]=i+n;
111         }
112         gx.init(2*n);
113         while(m--){
114             scanf("%d%d",&a,&b);
115             a=mp[a];
116             b=mp[b];
117             gx.add(a,b+(b>n?-n:n));
118             gx.add(b,a+(a>n?-n:n));
119         }
120         puts(gx.solve()?"yes":"no");
121     }
122     return 0;
123 }
View Code

 

  1 #include<cstdio>
  2 #include<cstring>
  3 #include<queue>
  4 #include<stack>
  5 #include<map>
  6 #define mt(a,b) memset(a,b,sizeof(a))
  7 using namespace std;
  8 class TwoSat { ///2-sat判定,solve函数返回是否有解,i结点的对称结点i^为i+n,
  9     static const int ME=10010;///边的个数
 10     static const int MV=2010;///点的个数
 11     struct G {
 12         struct E {
 13             int u,v,next;
 14         } e[ME];
 15         int le,head[MV];
 16         void init() {
 17             le=0;
 18             mt(head,-1);
 19         }
 20         void add(int u,int v) {
 21             e[le].u=u;
 22             e[le].v=v;
 23             e[le].next=head[u];
 24             head[u]=le++;
 25         }
 26     } g;
 27     class Tarjan { ///有向图强连通分量缩点o(MV+ME)
 28         int Index,Bcnt,num[MV],belong[MV],dfn[MV],low[MV];
 29         bool instack[MV];
 30         stack<int> s;
 31         void tarjan(int u) {
 32             dfn[u]=low[u]=++Index;
 33             instack[u]=true;
 34             s.push(u);
 35             int v;
 36             for(int i=g.head[u]; ~i; i=g.e[i].next) {
 37                 v=g.e[i].v;
 38                 if(!dfn[v]) {
 39                     tarjan(v);
 40                     low[u]=min(low[u],low[v]);
 41                 } else if(instack[v]) {
 42                     low[u]=min(low[u],dfn[v]);
 43                 }
 44             }
 45             if(dfn[u]==low[u]) {
 46                 Bcnt++;
 47                 do {
 48                     v=s.top();
 49                     s.pop();
 50                     instack[v]=false;
 51                     belong[v]=Bcnt;
 52                     num[Bcnt]++;
 53                 } while(u!=v);
 54             }
 55         }
 56     public:
 57         G g;
 58         void init() {
 59             g.init();
 60             Index=Bcnt=0;
 61             mt(num,0);
 62             mt(dfn,0);
 63             mt(low,0);
 64             mt(instack,0);
 65             while(!s.empty()) s.pop();
 66         }
 67         void add(int u,int v) {
 68             g.add(u,v);
 69         }
 70         void solve(int n) {///传入点数,点下标1开始
 71             for(int i=1; i<=n; i++) {
 72                 if(!dfn[i]) {
 73                     tarjan(i);
 74                 }
 75             }
 76         }
 77         int getbcnt() {///强连通分量的个数
 78             return Bcnt;
 79         }
 80         int getbelong(int id) {///属于哪个分量,分量下标1开始
 81             return belong[id];
 82         }
 83         int getnum(int id) {///某个分量的点的个数
 84             return num[id];
 85         }
 86     } T;
 87     class Unitenode { ///缩点
 88         G ug;
 89         int n,in[MV];
 90         bool mat[MV][MV];
 91         queue<int> q;
 92     public:
 93         void init(int tn) {
 94             n=tn;
 95             ug.init();
 96             mt(in,0);
 97             for(int i=1;i<=n;i++)
 98                 for(int j=1;j<=n;j++)
 99                     mat[i][j]=i==j?true:false;
100         }
101         void add(int u,int v) {
102             if(!mat[u][v]) {
103                 in[v]++;
104                 mat[u][v]=true;
105                 ug.add(u,v);
106             }
107         }
108         void solve(int tp[]) {
109             while(!q.empty()) q.pop();
110             for(int i=1; i<=n; i++) {
111                 if(!in[i]) {
112                     q.push(i);
113                 }
114             }
115             int ret=1;
116             while(!q.empty()) {
117                 int u=q.front();
118                 q.pop();
119                 tp[ret++]=u;
120                 for(int i=ug.head[u]; ~i; i=ug.e[i].next) {
121                     int v=ug.e[i].v;
122                     in[v]--;
123                     if(!in[v]) {
124                         q.push(v);
125                     }
126                 }
127             }
128         }
129     } U;
130     void unite() {
131         U.init(T.getbcnt());
132         for(int i=1; i<=n; i++) {
133             for(int j=T.g.head[i]; ~j; j=T.g.e[j].next) {
134                 U.add(T.getbelong(i),T.getbelong(T.g.e[j].v));
135             }
136         }
137     }
138     int n,tp[MV];
139     bool flag[MV];
140 public:
141     void init(int tn) { ///传入判定结点2*n
142         n=tn;
143         T.init();
144     }
145     void add(int u,int v) { ///如果取u必须取v结点添加边u->v,下标1开始
146         T.add(u,v);
147     }
148     bool solve() {
149         T.solve(n);
150         for(int i=1,z=n/2; i<=z; i++) {
151             if(T.getbelong(i)==T.getbelong(i+z))return false;
152         }
153         return true;
154     }
155     void output(bool ans[]) {///ans[i]==false则选择i结点,否则选择i^结点
156         unite();
157         U.solve(tp);
158         mt(flag,0);
159         for(int i=T.getbcnt(); i>0; i--) {
160             for(int j=1,y; j<=n; j++) {
161                 if(j>n/2)y=j-n/2;
162                 else y=j;
163                 if(!flag[y]&&T.getbelong(j)==tp[i]) {
164                     flag[y]=true;
165                     if(j>n/2) {
166                         ans[j-n/2]=true;
167                     } else {
168                         ans[j]=false;
169                     }
170                 }
171             }
172         }
173     }
174 } gx;
175 int mp[3010];
176 int main() {
177     int n,m,x,y,z;
178     while(~scanf("%d%d",&n,&m)) {
179         gx.init(n*2);
180         int myid=1;
181         for(int i=0; i<n; i++) {
182             scanf("%d%d%d",&x,&y,&z);
183             mp[x]=myid;
184             mp[y]=myid+n;
185             mp[z]=myid+n;
186             myid++;
187         }
188         for(int i=0; i<m; i++) {
189             scanf("%d%d",&x,&y);
190             x=mp[x];
191             y=mp[y];
192             gx.add(x,y+(y>n?-n:n));
193             gx.add(y,x+(x>n?-n:n));
194         }
195         if(gx.solve()) {
196             puts("yes");
197         } else {
198             puts("no");
199         }
200     }
201     return 0;
202 }
View Code

 

 

Party http://acm.hdu.edu.cn/showproblem.php?pid=3062

根据矛盾关系建图,一对夫妻正好是2sat中的a 和 a‘ 点

 

精简版

  1 #include<cstdio>
  2 #include<cstring>
  3 #include<queue>
  4 #include<stack>
  5 #include<map>
  6 #define mt(a,b) memset(a,b,sizeof(a))
  7 using namespace std;
  8 class TwoSat { ///2-sat判定,solve函数返回是否有解,i结点的对称结点i^为i+n,
  9     static const int ME=1600010;///边的个数
 10     static const int MV=4010;///点的个数
 11     struct G {
 12         struct E {
 13             int u,v,next;
 14         } e[ME];
 15         int le,head[MV];
 16         void init() {
 17             le=0;
 18             mt(head,-1);
 19         }
 20         void add(int u,int v) {
 21             e[le].u=u;
 22             e[le].v=v;
 23             e[le].next=head[u];
 24             head[u]=le++;
 25         }
 26     } g;
 27     class Tarjan { ///有向图强连通分量缩点o(MV+ME)
 28         int Index,Bcnt,num[MV],belong[MV],dfn[MV],low[MV];
 29         bool instack[MV];
 30         stack<int> s;
 31         void tarjan(int u) {
 32             dfn[u]=low[u]=++Index;
 33             instack[u]=true;
 34             s.push(u);
 35             int v;
 36             for(int i=g.head[u]; ~i; i=g.e[i].next) {
 37                 v=g.e[i].v;
 38                 if(!dfn[v]) {
 39                     tarjan(v);
 40                     low[u]=min(low[u],low[v]);
 41                 } else if(instack[v]) {
 42                     low[u]=min(low[u],dfn[v]);
 43                 }
 44             }
 45             if(dfn[u]==low[u]) {
 46                 Bcnt++;
 47                 do {
 48                     v=s.top();
 49                     s.pop();
 50                     instack[v]=false;
 51                     belong[v]=Bcnt;
 52                     num[Bcnt]++;
 53                 } while(u!=v);
 54             }
 55         }
 56     public:
 57         G g;
 58         void init() {
 59             g.init();
 60             Index=Bcnt=0;
 61             mt(num,0);
 62             mt(dfn,0);
 63             mt(low,0);
 64             mt(instack,0);
 65             while(!s.empty()) s.pop();
 66         }
 67         void add(int u,int v) {
 68             g.add(u,v);
 69         }
 70         void solve(int n) {///传入点数,点下标1开始
 71             for(int i=1; i<=n; i++) {
 72                 if(!dfn[i]) {
 73                     tarjan(i);
 74                 }
 75             }
 76         }
 77         int getbcnt() {///强连通分量的个数
 78             return Bcnt;
 79         }
 80         int getbelong(int id) {///属于哪个分量,分量下标1开始
 81             return belong[id];
 82         }
 83         int getnum(int id) {///某个分量的点的个数
 84             return num[id];
 85         }
 86     } T;
 87     int n;
 88 public:
 89     void init(int tn) { ///传入判定结点2*n
 90         n=tn;
 91         T.init();
 92     }
 93     void add(int u,int v) { ///如果取u必须取v结点添加边u->v,下标1开始
 94         T.add(u,v);
 95     }
 96     bool solve() {
 97         T.solve(n);
 98         for(int i=1,z=n/2; i<=z; i++) {
 99             if(T.getbelong(i)==T.getbelong(i+z))return false;
100         }
101         return true;
102     }
103 } gx;
104 int n;
105 int getfan(int x){
106     if(x<=n) return x+n;
107     return x-n;
108 }
109 int main(){
110     int m,a,b,c,d;
111     while(~scanf("%d%d",&n,&m)){
112         gx.init(2*n);
113         while(m--){
114             scanf("%d%d%d%d",&a,&b,&c,&d);
115             a++;
116             b++;
117             a+=c*n;
118             b+=d*n;
119             gx.add(a,getfan(b));
120             gx.add(b,getfan(a));
121         }
122         puts(gx.solve()?"YES":"NO");
123     }
124     return 0;
125 }
View Code

 

 

  1 #include<cstdio>
  2 #include<cstring>
  3 #include<queue>
  4 #include<stack>
  5 #include<map>
  6 #define mt(a,b) memset(a,b,sizeof(a))
  7 using namespace std;
  8 class TwoSat { ///2-sat判定,solve函数返回是否有解,i结点的对称结点i^为i+n,
  9     static const int ME=1000010;///边的个数
 10     static const int MV=2010;///点的个数
 11     struct G {
 12         struct E {
 13             int u,v,next;
 14         } e[ME];
 15         int le,head[MV];
 16         void init() {
 17             le=0;
 18             mt(head,-1);
 19         }
 20         void add(int u,int v) {
 21             e[le].u=u;
 22             e[le].v=v;
 23             e[le].next=head[u];
 24             head[u]=le++;
 25         }
 26     } g;
 27     class Tarjan { ///有向图强连通分量缩点o(MV+ME)
 28         int Index,Bcnt,num[MV],belong[MV],dfn[MV],low[MV];
 29         bool instack[MV];
 30         stack<int> s;
 31         void tarjan(int u) {
 32             dfn[u]=low[u]=++Index;
 33             instack[u]=true;
 34             s.push(u);
 35             int v;
 36             for(int i=g.head[u]; ~i; i=g.e[i].next) {
 37                 v=g.e[i].v;
 38                 if(!dfn[v]) {
 39                     tarjan(v);
 40                     low[u]=min(low[u],low[v]);
 41                 } else if(instack[v]) {
 42                     low[u]=min(low[u],dfn[v]);
 43                 }
 44             }
 45             if(dfn[u]==low[u]) {
 46                 Bcnt++;
 47                 do {
 48                     v=s.top();
 49                     s.pop();
 50                     instack[v]=false;
 51                     belong[v]=Bcnt;
 52                     num[Bcnt]++;
 53                 } while(u!=v);
 54             }
 55         }
 56     public:
 57         G g;
 58         void init() {
 59             g.init();
 60             Index=Bcnt=0;
 61             mt(num,0);
 62             mt(dfn,0);
 63             mt(low,0);
 64             mt(instack,0);
 65             while(!s.empty()) s.pop();
 66         }
 67         void add(int u,int v) {
 68             g.add(u,v);
 69         }
 70         void solve(int n) {///传入点数,点下标1开始
 71             for(int i=1; i<=n; i++) {
 72                 if(!dfn[i]) {
 73                     tarjan(i);
 74                 }
 75             }
 76         }
 77         int getbcnt() {///强连通分量的个数
 78             return Bcnt;
 79         }
 80         int getbelong(int id) {///属于哪个分量,分量下标1开始
 81             return belong[id];
 82         }
 83         int getnum(int id) {///某个分量的点的个数
 84             return num[id];
 85         }
 86     } T;
 87     class Unitenode { ///缩点
 88         G ug;
 89         int n,in[MV];
 90         bool mat[MV][MV];
 91         queue<int> q;
 92     public:
 93         void init(int tn) {
 94             n=tn;
 95             ug.init();
 96             mt(in,0);
 97             for(int i=1;i<=n;i++)
 98                 for(int j=1;j<=n;j++)
 99                     mat[i][j]=i==j?true:false;
100         }
101         void add(int u,int v) {
102             if(!mat[u][v]) {
103                 in[v]++;
104                 mat[u][v]=true;
105                 ug.add(u,v);
106             }
107         }
108         void solve(int tp[]) {
109             while(!q.empty()) q.pop();
110             for(int i=1; i<=n; i++) {
111                 if(!in[i]) {
112                     q.push(i);
113                 }
114             }
115             int ret=1;
116             while(!q.empty()) {
117                 int u=q.front();
118                 q.pop();
119                 tp[ret++]=u;
120                 for(int i=ug.head[u]; ~i; i=ug.e[i].next) {
121                     int v=ug.e[i].v;
122                     in[v]--;
123                     if(!in[v]) {
124                         q.push(v);
125                     }
126                 }
127             }
128         }
129     } U;
130     void unite() {
131         U.init(T.getbcnt());
132         for(int i=1; i<=n; i++) {
133             for(int j=T.g.head[i]; ~j; j=T.g.e[j].next) {
134                 U.add(T.getbelong(i),T.getbelong(T.g.e[j].v));
135             }
136         }
137     }
138     int n,tp[MV];
139     bool flag[MV];
140 public:
141     void init(int tn) { ///传入判定结点2*n
142         n=tn;
143         T.init();
144     }
145     void add(int u,int v) { ///如果取u必须取v结点添加边u->v,下标1开始
146         T.add(u,v);
147     }
148     bool solve() {
149         T.solve(n);
150         for(int i=1,z=n/2; i<=z; i++) {
151             if(T.getbelong(i)==T.getbelong(i+z))return false;
152         }
153         return true;
154     }
155     void output(bool ans[]) {///ans[i]==false则选择i结点,否则选择i^结点
156         unite();
157         U.solve(tp);
158         mt(flag,0);
159         for(int i=T.getbcnt(); i>0; i--) {
160             for(int j=1,y; j<=n; j++) {
161                 if(j>n/2)y=j-n/2;
162                 else y=j;
163                 if(!flag[y]&&T.getbelong(j)==tp[i]) {
164                     flag[y]=true;
165                     if(j>n/2) {
166                         ans[j-n/2]=true;
167                     } else {
168                         ans[j]=false;
169                     }
170                 }
171             }
172         }
173     }
174 } gx;
175 int main() {
176     int n,m,a,b,c,d;
177     while(~scanf("%d%d",&n,&m)) {
178         gx.init(n*2);
179         for(int i=0; i<m; i++) {
180             scanf("%d%d%d%d",&a,&b,&c,&d);
181             a++;
182             b++;
183             if(c==0&&d==0) {
184                 gx.add(a,b+n);
185                 gx.add(b,a+n);
186             } else if(c==1&&d==1) {
187                 gx.add(a+n,b);
188                 gx.add(b+n,a);
189             } else if(c==0&&d==1) {
190                 gx.add(a,b);
191                 gx.add(b+n,a+n);
192             } else if(c==1&&d==0) {
193                 gx.add(a+n,b+n);
194                 gx.add(b,a);
195             }
196         }
197         if(gx.solve()) {
198             puts("YES");
199         } else {
200             puts("NO");
201         }
202     }
203     return 0;
204 }
View Code

 

 

D. Ring Road 2 http://codeforces.com/problemset/problem/27/D

 

对m条边 ,每条边不是里面就是外面 ,所以就是2sat的 a 和 a’ ,然后枚举两条边,如果相交,那 i 在里面时 必须 j 在外面。

 

  1 #include<cstdio>
  2 #include<cstring>
  3 #include<queue>
  4 #include<stack>
  5 #include<map>
  6 #define mt(a,b) memset(a,b,sizeof(a))
  7 using namespace std;
  8 class TwoSat { ///2-sat判定,solve函数返回是否有解,i结点的对称结点i^为i+n,
  9     static const int ME=1000010;///边的个数
 10     static const int MV=2010;///点的个数
 11     struct G {
 12         struct E {
 13             int u,v,next;
 14         } e[ME];
 15         int le,head[MV];
 16         void init() {
 17             le=0;
 18             mt(head,-1);
 19         }
 20         void add(int u,int v) {
 21             e[le].u=u;
 22             e[le].v=v;
 23             e[le].next=head[u];
 24             head[u]=le++;
 25         }
 26     } g;
 27     class Tarjan { ///有向图强连通分量缩点o(MV+ME)
 28         int Index,Bcnt,num[MV],belong[MV],dfn[MV],low[MV];
 29         bool instack[MV];
 30         stack<int> s;
 31         void tarjan(int u) {
 32             dfn[u]=low[u]=++Index;
 33             instack[u]=true;
 34             s.push(u);
 35             int v;
 36             for(int i=g.head[u]; ~i; i=g.e[i].next) {
 37                 v=g.e[i].v;
 38                 if(!dfn[v]) {
 39                     tarjan(v);
 40                     low[u]=min(low[u],low[v]);
 41                 } else if(instack[v]) {
 42                     low[u]=min(low[u],dfn[v]);
 43                 }
 44             }
 45             if(dfn[u]==low[u]) {
 46                 Bcnt++;
 47                 do {
 48                     v=s.top();
 49                     s.pop();
 50                     instack[v]=false;
 51                     belong[v]=Bcnt;
 52                     num[Bcnt]++;
 53                 } while(u!=v);
 54             }
 55         }
 56     public:
 57         G g;
 58         void init() {
 59             g.init();
 60             Index=Bcnt=0;
 61             mt(num,0);
 62             mt(dfn,0);
 63             mt(low,0);
 64             mt(instack,0);
 65             while(!s.empty()) s.pop();
 66         }
 67         void add(int u,int v) {
 68             g.add(u,v);
 69         }
 70         void solve(int n) {///传入点数,点下标1开始
 71             for(int i=1; i<=n; i++) {
 72                 if(!dfn[i]) {
 73                     tarjan(i);
 74                 }
 75             }
 76         }
 77         int getbcnt() {///强连通分量的个数
 78             return Bcnt;
 79         }
 80         int getbelong(int id) {///属于哪个分量,分量下标1开始
 81             return belong[id];
 82         }
 83         int getnum(int id) {///某个分量的点的个数
 84             return num[id];
 85         }
 86     } T;
 87     class Unitenode { ///缩点
 88         G ug;
 89         int n,in[MV];
 90         bool mat[MV][MV];
 91         queue<int> q;
 92     public:
 93         void init(int tn) {
 94             n=tn;
 95             ug.init();
 96             mt(in,0);
 97             for(int i=1;i<=n;i++)
 98                 for(int j=1;j<=n;j++)
 99                     mat[i][j]=i==j?true:false;
100         }
101         void add(int u,int v) {
102             if(!mat[u][v]) {
103                 in[v]++;
104                 mat[u][v]=true;
105                 ug.add(u,v);
106             }
107         }
108         void solve(int tp[]) {
109             while(!q.empty()) q.pop();
110             for(int i=1; i<=n; i++) {
111                 if(!in[i]) {
112                     q.push(i);
113                 }
114             }
115             int ret=1;
116             while(!q.empty()) {
117                 int u=q.front();
118                 q.pop();
119                 tp[ret++]=u;
120                 for(int i=ug.head[u]; ~i; i=ug.e[i].next) {
121                     int v=ug.e[i].v;
122                     in[v]--;
123                     if(!in[v]) {
124                         q.push(v);
125                     }
126                 }
127             }
128         }
129     } U;
130     void unite() {
131         U.init(T.getbcnt());
132         for(int i=1; i<=n; i++) {
133             for(int j=T.g.head[i]; ~j; j=T.g.e[j].next) {
134                 U.add(T.getbelong(i),T.getbelong(T.g.e[j].v));
135             }
136         }
137     }
138     int n,tp[MV];
139     bool flag[MV];
140 public:
141     void init(int tn) { ///传入判定结点2*n
142         n=tn;
143         T.init();
144     }
145     void add(int u,int v) { ///如果取u必须取v结点添加边u->v,下标1开始
146         T.add(u,v);
147     }
148     bool solve() {
149         T.solve(n);
150         for(int i=1,z=n/2; i<=z; i++) {
151             if(T.getbelong(i)==T.getbelong(i+z))return false;
152         }
153         return true;
154     }
155     void output(bool ans[]) {///ans[i]==false则选择i结点,否则选择i^结点
156         unite();
157         U.solve(tp);
158         mt(flag,0);
159         for(int i=T.getbcnt(); i>0; i--) {
160             for(int j=1,y; j<=n; j++) {
161                 if(j>n/2)y=j-n/2;
162                 else y=j;
163                 if(!flag[y]&&T.getbelong(j)==tp[i]) {
164                     flag[y]=true;
165                     if(j>n/2) {
166                         ans[j-n/2]=true;
167                     } else {
168                         ans[j]=false;
169                     }
170                 }
171             }
172         }
173     }
174 } gx;
175 const int M=128;
176 struct IN {
177     int x,y;
178 } in[M];
179 bool ok(int i,int j) {
180     if(in[i].x<in[j].x&&in[j].x<in[i].y&&in[i].y<in[j].y) return true;
181     return false;
182 }
183 bool judge(int i,int j) {
184     if(ok(i,j)||ok(j,i)) return true;
185     return false;
186 }
187 bool ans[M];
188 int main() {
189     int n,m;
190     while(~scanf("%d%d",&n,&m)) {
191         gx.init(m*2);
192         for(int i=1; i<=m; i++) {
193             scanf("%d%d",&in[i].x,&in[i].y);
194             if(in[i].x>in[i].y) swap(in[i].x,in[i].y);
195         }
196         for(int i=1; i<=m; i++) {
197             for(int j=i+1; j<=m; j++) {
198                 if(judge(i,j)) {
199 //                    printf("%d %d\n",i,j);
200                     gx.add(i,j+m);
201                     gx.add(j,i+m);
202                     gx.add(i+m,j);
203                     gx.add(j+m,i);
204                 }
205             }
206         }
207         if(gx.solve()) {
208             gx.output(ans);
209             for(int i=1; i<=m; i++) {
210                 if(ans[i]) printf("i");
211                 else       printf("o");
212             }
213             puts("");
214         } else {
215             puts("Impossible");
216         }
217     }
218     return 0;
219 }
View Code

 

 

 

end

posted on 2014-09-11 13:12  gaolzzxin  阅读(427)  评论(0编辑  收藏  举报