2-SAT
模型一:两者(A,B)不能同时取
那么选择了A就只能选择B’,选择了B就只能选择A’
连边A→B’,B→A’
那么选择了A’就只能选择B,选择了B’就只能选择A
连边A’→B,B’→A
那么选择了A,就只能选择B,选择了B就只能选择A,选择了A’就只能选择B’,选择了B’就只能选择A’
连边A→B,B→A,A’→B’,B’→A’
练习hdu3715:http://acm.hdu.edu.cn/showproblem.php?pid=3715
#include<bits/stdc++.h>
using namespace std;
const int maxn = 10050;
stack<int> S;
bool isinstack[maxn];
int low[maxn], dfn[maxn];
int ID[maxn];
int head[maxn];
int n, m, scc_num, index, edgecnt;
struct P
{
int to, next, cost;
}edge[maxn*10];
void add(int u, int v)
{
edge[edgecnt].to = v;
edge[edgecnt].next = head[u];
head[u] = edgecnt++;
}
void TarDFS(int u)
{
low[u] = dfn[u] = index++;
isinstack[u] = 1;
S.push(u);
for(int i = head[u]; ~i; i = edge[i].next)
{
int v = edge[i].to;
if(dfn[v] == -1)
{
TarDFS(v);
low[u] = min(low[u], low[v]);
}
else if(isinstack[v])
{
low[u] = min(low[u], dfn[v]);
}
}
if(dfn[u] ==low[u])
{
scc_num++;
while(S.top() != u)
{
isinstack[S.top()] = 0;
ID[S.top()] = scc_num;
S.pop();
}
isinstack[u] = 0;
ID[u] = scc_num;
S.pop();
}
}
int Tarjan()
{
scc_num = 0;
index = 1;
for(int i = 0; i < 2 * n; i++)
{
if(dfn[i] == -1)
{
TarDFS(i);
}
}
return scc_num;
}
void init()
{
memset(dfn, -1, sizeof(dfn));
memset(head, -1, sizeof(head));
memset(isinstack, 0, sizeof(isinstack));
edgecnt = 0;
}
int a[maxn], b[maxn], c[maxn];
bool check(int dep)
{
init();
for(int i = 0; i < dep; i++)
{
if(c[i] == 1)
{
add(a[i] * 2, b[i] * 2);
add(a[i] * 2 + 1, b[i] * 2 + 1);
add(b[i] * 2, a[i] * 2);
add(b[i] * 2 + 1, a[i] * 2 + 1);
}
else if(c[i] == 2)
{
add(a[i] * 2, b[i] * 2 + 1);
add(b[i] * 2, a[i] * 2 + 1);
}
else
{
add(a[i] * 2 + 1, b[i] * 2);
add(b[i] * 2 + 1, a[i] * 2);
}
}
Tarjan();
for(int i = 0; i < n; i++)
{
if(ID[2 * i] == ID[2 * i + 1])
return false;
}
return true;
}
int main()
{
ios_base::sync_with_stdio(0);
cin.tie(0); cout.tie(0);
int t;
cin >> t;
while(t--)
{
cin >> n >> m;
init();
for(int i = 0; i < m; i++)
{
cin >> a[i] >> b[i] >> c[i];
}
int l = 1, r = m;
int ans = 0;
while(l <= r)
{
int mid = (l + r) >> 1;
//cout << mid << endl;
if(check(mid))
{
ans = mid;
l = mid + 1;
}
else
r = mid - 1;
}
cout << ans << endl;
}
return 0;
}