一个很简单的2-sat的题;
不过比较难想到;
其实也不是很难,可能接触的少了吧!
1 #include<cstdio> 2 #include<vector> 3 #define maxn 10009 4 using namespace std; 5 6 struct twosat 7 { 8 int n; 9 vector<int>g[maxn*2]; 10 bool mark[maxn*2]; 11 int s[maxn*2],c; 12 13 bool dfs(int x) 14 { 15 if(mark[x^1])return 0; 16 if(mark[x])return 1; 17 mark[x]=1; 18 s[c++]=x; 19 for(int i=0; i<g[x].size(); i++) 20 if(!dfs(g[x][i]))return 0; 21 return 1; 22 } 23 void init(int n) 24 { 25 this->n=n; 26 for(int i=0; i<2*n; i++)g[i].clear(); 27 memset(mark,0,sizeof mark); 28 } 29 void add_clase(int x,int y) 30 { 31 g[x].push_back(y); 32 } 33 bool solve(int mid) 34 { 35 for(int i=2; i<mid*2; i+=2) 36 if(!mark[i]&&!mark[i+1]) 37 { 38 c=0; 39 if(!dfs(i)) 40 { 41 while(c>0)mark[s[--c]]=0; 42 if(!dfs(i+1))return 0; 43 } 44 } 45 return 1; 46 } 47 } getans; 48 int a[maxn],b[maxn],c[maxn]; 49 int main() 50 { 51 int n,m,t; 52 scanf("%d",&t); 53 while(t--) 54 { 55 scanf("%d%d",&n,&m); 56 for(int i=0; i<m; i++) 57 scanf("%d%d%d",&a[i],&b[i],&c[i]); 58 int l=0,r=m; 59 int ans=0; 60 while(l<=r) 61 { 62 int mid=(l+r)/2; 63 getans.init(n<<1); 64 for(int i=0;i<mid;i++) 65 { 66 if(c[i]==0) 67 { 68 getans.add_clase(a[i]<<1,b[i]<<1|1); 69 getans.add_clase(b[i]<<1,a[i]<<1|1); 70 } 71 else if(c[i]==1) 72 { 73 getans.add_clase(a[i]<<1|1,b[i]<<1|1); 74 getans.add_clase(a[i]<<1,b[i]<<1); 75 getans.add_clase(b[i]<<1|1,a[i]<<1|1); 76 getans.add_clase(b[i]<<1,a[i]<<1); 77 } 78 else if(c[i]==2) 79 { 80 getans.add_clase(a[i]<<1|1,b[i]<<1); 81 getans.add_clase(b[i]<<1|1,a[i]<<1); 82 } 83 } 84 if(!getans.solve(mid))r=mid-1; 85 else {ans=mid;l=mid+1;} 86 } 87 printf("%d ",ans); 88 } 89 return 0; 90 }