标签:style blog http color io os ar for art
把队长和两个队员当成对称的两个点,有你没我,有我没你。
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 }
根据矛盾关系建图
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 }
D. Ring Road 2 http://codeforces.com/problemset/problem/27/D
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 }
end
标签:style blog http color io os ar for art
原文地址:http://www.cnblogs.com/gaolzzxin/p/3966260.html