/****************************************************************************************************
二分+2-sat,二分程序能到达的最远步骤,尼玛二分写错了吃了一次WA。。。
****************************************************************************************************/
#include <iostream>
#include <functional>
#include <algorithm>
//#include <hash_map> //Visual C++ lib
#include <complex>
#include <cstdlib>
#include <cstring>
#include <fstream>
#include <sstream>
#include <utility>
#include <bitset>
#include <cctype>
#include <cstdio>
#include <limits>
#include <memory>
#include <string>
#include <vector>
#include <cmath>
#include <ctime>
#include <queue>
#include <stack>
#include <list>
#include <map>
#include <set>
using namespace std;
#define LOWBIT(x) ( (x) & ( (x) ^ ( (x) - 1 ) ) )
#define CLR(x, k) memset((x), (k), sizeof(x))
#define CPY(t, s) memcpy((t), (s), sizeof(s))
#define SC(t, s) static_cast<t>(s)
#define LEN(s) static_cast<int>( strlen((s)) )
#define SZ(s) static_cast<int>( (s).size() )
typedef double LF;
//typedef long long LL; //GNU C++
//typedef unsigned long long ULL;
typedef __int64 LL; //Visual C++ 2010
typedef unsigned __int64 ULL;
typedef pair<int, int> PII;
typedef pair<LL, LL> PLL;
typedef pair<double, double> PDD;
//typedef hash_map<int, int>::iterator HMI;
typedef map<int, int>::iterator MI;
typedef vector<int>::iterator VI;
typedef list<int>::iterator LI;
typedef set<int>::iterator SI;
template <typename T>
T sqa(const T &x)
{
return x * x;
}
const int INF_INT = 0x3f3f3f3f;
const LL INF_LL = 0x7fffffffffffffffLL; //15f
const double oo = 10e9;
const double eps = 10e-9;
const double PI = acos(-1.0);
const int MAXN = 204;
const int MAXV = MAXN << 1;
const int MAXE = MAXV * MAXV;
struct Edges
{
int end;
int rk;
int next;
}edges[MAXE];
int ecnt, head[MAXV];
int test, n, m;
int id[MAXV], pre[MAXV], low[MAXV], S[MAXV], stop, cnt, scnt;
void inline add_edge(int u, int v, int r)
{
edges[ecnt].end = v;
edges[ecnt].rk = r;
edges[ecnt].next = head[u];
head[u] = ecnt++;
return ;
}
void tarjan(int u, int n, int key)
{
int t, minc = low[u] = pre[u] = cnt++;
S[stop++] = u;
for (int i = head[u]; i != -1; i = edges[i].next)
{
if (edges[i].rk > key)
{
continue ;
}
int v = edges[i].end;
if (-1 == pre[v])
{
tarjan(v, n, key);
}
minc = min(minc, low[v]);
}
if (minc < low[u])
{
low[u] = minc;
return ;
}
do
{
id[ t = S[--stop] ] = scnt;
low[t] = n;
}
while (t != u);
++scnt;
return ;
}
bool _2sat(int key)
{
stop = cnt = scnt = 0;
CLR(pre, -1);
n <<= 1;
for (int i = 0; i < n; ++i)
{
if (-1 == pre[i])
{
tarjan(i, n, key);
}
}
n >>= 1;
for (int i = 0; i < n; ++i)
{
if (id[i] == id[i + n])
{
return false;
}
}
return true;
}
int bisearch()
{
int l = 0, r = m - 1, mid = (l + r) / 2, res = (l + r) / 2;
while (l <= r)
{
mid = (l + r) / 2;
if (_2sat(mid))
{
res = mid;
l = mid + 1;
}
else
{
r = mid - 1;
}
}
return res;
}
void ace()
{
int a, b, c;
for (scanf("%d", &test); test--; )
{
scanf("%d %d", &n, &m);
ecnt = 0;
CLR(head, -1);
for (int i = 0; i < m; ++i)
{
scanf("%d %d %d", &a, &b, &c);
if (2 == c)
{
add_edge(a, b + n, i);
add_edge(b, a + n, i);
}
else if (1 == c)
{
add_edge(a, b, i);
add_edge(b, a, i);
add_edge(a + n, b + n, i);
add_edge(b + n, a + n, i);
}
else
{
add_edge(a + n, b, i);
add_edge(b + n, a, i);
}
}
printf("%d\n", bisearch() + 1);
}
return ;
}
int main()
{
ace();
return 0;
}
HDU 3715 2-sat
最新推荐文章于 2021-08-18 12:09:29 发布