HDU 3062
简单的判断,裸的2SAT
#include <cstdio>
#include <cstring>
const int N = 2100;
const int M = 1100 * 1000 * 2;
struct Node
{
int adj,next;
} node[M];
struct TT
{
int DFN,LOW,belongs;
} num[N];
int first[N],n,e;
bool instack[N];
int stack[N],b_cnt,idx,top;
void init()
{
e=0;
for(int i=0; i<=2*n; i++)
{
first[i]=-1;
num[i].DFN=num[i].LOW=0;
num[i].belongs=0;
instack[i]=false;
}
}
void insertEdge(int u,int v)
{
node[e].adj=v;
node[e].next=first[u];
first[u]=e++;;
}
void Tarjan(int u)
{
int v;
num[u].DFN=num[u].LOW=(++idx);
instack[u]=true;
stack[++top]=u;
for(int p=first[u]; p!=-1; p=node[p].next)
{
v=node[p].adj;
if(!num[v].DFN)
{
Tarjan(v);
if(num[v].LOW<num[u].LOW)
num[u].LOW=num[v].LOW;
}
else if(instack[v]&&num[v].DFN<num[u].LOW)
num[u].LOW=num[v].DFN;
}
if(num[u].DFN==num[u].LOW)
{
b_cnt++;
do
{
v=stack[top--];
instack[v]=false;
num[v].belongs=b_cnt;
}
while(u!=v);
}
}
bool Tarjan_SCC()
{
b_cnt=top=idx=0;
for(int i=0; i<2*n; i++)
if(!num[i].DFN) Tarjan(i);
for(int i=0; i<2*n; i+=2)
if(num[i].belongs==num[i^1].belongs)
return false;
return true;
}
int main()
{
int m;
while (scanf("%d%d",&n,&m)==2)
{
init();
int a,b,c,d;
for (int i=0; i<m; ++i)
{
scanf("%d%d%d%d",&a,&b,&c,&d);
if(c) a= 2 * a + 1;
else a = 2 * a;
if(d) b= 2 * b + 1;
else b = 2 * b;
insertEdge(a, b^1);
insertEdge(b, a^1);
}
if (!Tarjan_SCC())
{
printf("NO\n");
}
else
printf("YES\n");
}
return 0;
}
hdu 1824 题目描述不是特别清楚吧
#include <cstdio>
#include <cstring>
const int N = 1010 * 6;
const int M = 100000;
struct Node
{
int adj,next;
} node[M];
struct TT
{
int DFN,LOW,belongs;
} num[N];
int first[N],n,e;
bool instack[N];
int stack[N],b_cnt,idx,top;
void init()
{
e=0;
for(int i=0; i<=6*n; i++)
{
first[i]=-1;
num[i].DFN=num[i].LOW=0;
num[i].belongs=0;
instack[i]=false;
}
}
void insertEdge(int u,int v)
{
node[e].adj=v;
node[e].next=first[u];
first[u]=e++;;
}
void Tarjan(int u)
{
int v;
num[u].DFN=num[u].LOW=(++idx);
instack[u]=true;
stack[++top]=u;
for(int p=first[u]; p!=-1; p=node[p].next)
{
v=node[p].adj;
if(!num[v].DFN)
{
Tarjan(v);
if(num[v].LOW<num[u].LOW)
num[u].LOW=num[v].LOW;
}
else if(instack[v]&&num[v].DFN<num[u].LOW)
num[u].LOW=num[v].DFN;
}
if(num[u].DFN==num[u].LOW)
{
b_cnt++;
do
{
v=stack[top--];
instack[v]=false;
num[v].belongs=b_cnt;
}
while(u!=v);
}
}
bool Tarjan_SCC()
{
b_cnt=top=idx=0;
for(int i=0; i<6*n; i++)
if(!num[i].DFN) Tarjan(i);
for(int i=0; i<3*n; i++)
if(num[i].belongs==num[i+3*n].belongs)
return false;
return true;
}
int main()
{
int m;
while(scanf("%d%d", &n, &m) != EOF)
{
init();
int te = n * 3;
int a, b, c;
for(int i = 1; i <= n; i++)
{
scanf("%d%d%d", &a, &b, &c);
insertEdge(a, b + te);//a和b,c之间的互斥关系
insertEdge(a, c + te);
insertEdge(b, a + te);
insertEdge(c, a + te);
insertEdge(a + te, b);
insertEdge(a + te, c);
insertEdge(b + te, a);
insertEdge(c + te, a);
insertEdge(b, c);
insertEdge(c, b);
insertEdge(b + te, c + te);
insertEdge(c + te, b + te);
//
}
for(int i = 1; i <= m; i++)
{
scanf("%d%d", &a, &b);
insertEdge(a, b + te);
insertEdge(b, a + te);//注意a+te和b+te是没有影响的
}
if(Tarjan_SCC()) printf("yes\n");
else printf("no\n");
}
return 0;
}
hdu 3715 去年成都赛区的一道题目,二分一下就行了
#include <cstdio>
#include <cstring>
const int N = 210 * 3;
const int M = 210 * 210 * 3;
struct Node
{
int adj,next;
} node[M];
struct TT
{
int DFN,LOW,belongs;
} num[N];
int first[N],n,e,m;
bool instack[N];
int stack[N],b_cnt,idx,top;
int a[10010], b[10010], c[10010];
void init()
{
e=0;
memset(first, -1, sizeof(first));
memset(instack, 0, sizeof(instack));
for(int i=0; i<=2*n; i++)
{
num[i].DFN=num[i].LOW=0;
num[i].belongs=0;
}
}
void insertEdge(int u,int v)
{
node[e].adj=v;
node[e].next=first[u];
first[u]=e++;;
}
void Tarjan(int u)
{
int v;
num[u].DFN=num[u].LOW=(++idx);
instack[u]=true;
stack[++top]=u;
for(int p=first[u]; p!=-1; p=node[p].next)
{
v=node[p].adj;
if(!num[v].DFN)
{
Tarjan(v);
if(num[v].LOW<num[u].LOW)
num[u].LOW=num[v].LOW;
}
else if(instack[v]&&num[v].DFN<num[u].LOW)
num[u].LOW=num[v].DFN;
}
if(num[u].DFN==num[u].LOW)
{
b_cnt++;
do
{
v=stack[top--];
instack[v]=false;
num[v].belongs=b_cnt;
}
while(u!=v);
}
}
bool Tarjan_SCC()
{
b_cnt=top=idx=0;
for(int i=0; i<2*n; i++)
if(!num[i].DFN) Tarjan(i);
for(int i=0; i<2*n; i+=2)
if(num[i].belongs==num[i^1].belongs)
return false;
return true;
}
bool check(int dep)
{
init();
for(int i = 0; i < dep; i++)
{
int x = a[i];// 0..2*x 1..2*x+1
int y = b[i];
if(c[i] == 2)
{
//x[a] + y[b] != 2
insertEdge(x * 2 + 1, y * 2);
insertEdge(y * 2 + 1, x * 2);
}
else if(c[i] == 1)
{
insertEdge(x * 2 + 1, y * 2 + 1);
insertEdge(y * 2 + 1, x * 2 + 1);
insertEdge(x * 2, y * 2);
insertEdge(y * 2, x * 2);
}
else
{
insertEdge(x * 2, y * 2 + 1);
insertEdge(y * 2, x * 2 + 1);
}
}
if(Tarjan_SCC()) return true;
else return false;
}
void solve(int m)
{
int l = 0, r = m;
int ans = l;
while(l <= r)
{
int mid = (l + r) / 2;
//printf("mid = %d\n", mid);
if(check(mid))
{
if(mid > ans) ans = mid;
l = mid + 1;
}
else
r = mid - 1;
}
printf("%d\n", ans);
}
int main()
{
int T;
scanf("%d", &T);
while(T--)
{
scanf("%d%d", &n, &m);
for(int i = 0; i < m; i++)
{
scanf("%d%d%d", &a[i], &b[i], &c[i]);
}
solve(m);
}
return 0;
}
HDU 3622 去年天津赛区的一道预选赛的题目
#include <cstdio>
#include <cstring>
#include <cmath>
const double eps=1e-10;//注意这个要开大
struct T_T
{
int x,y;
} q[505];
struct Node
{
int adj,next;
} node[505*505];
struct TT
{
int DFN,LOW,belongs;
} num[505];
int first[550],n,e;
double map[505][505];
double min,max;
bool instack[550];
int stack[550],b_cnt,idx,top;
double len(int i,int j)
{
return sqrt(1.0*(q[i].x-q[j].x)*(q[i].x-q[j].x)+1.0*(q[i].y-q[j].y)*(q[i].y-q[j].y));
}
void init()
{
e=0;
for(int i=1; i<=2*n; i++)
{
first[i]=-1;
num[i].DFN=num[i].LOW=0;
num[i].belongs=0;
instack[i]=false;
}
}
void insertEdge(int u,int v)
{
node[e].adj=v;
node[e].next=first[u];
first[u]=e++;;
}
void Tarjan(int u)
{
int v;
num[u].DFN=num[u].LOW=(++idx);
instack[u]=true;
stack[++top]=u;
for(int p=first[u]; p!=-1; p=node[p].next)
{
v=node[p].adj;
if(!num[v].DFN)
{
Tarjan(v);
if(num[v].LOW<num[u].LOW)
num[u].LOW=num[v].LOW;
}
else if(instack[v]&&num[v].DFN<num[u].LOW)
num[u].LOW=num[v].DFN;
}
if(num[u].DFN==num[u].LOW)
{
b_cnt++;
do
{
v=stack[top--];
instack[v]=false;
num[v].belongs=b_cnt;
}
while(u!=v);
}
}
bool Tarjan_SCC()
{
b_cnt=top=idx=0;
for(int i=1; i<=2*n; i++)
if(!num[i].DFN) Tarjan(i);
for(int i=1; i<=n; i++)
if(num[i].belongs==num[i+n].belongs)
return false;
return true;
}
bool check(double d)
{
init();
for(int i=1; i<=n; i++)
for(int j=i+1; j<=n; j++)
{
if(map[i][j]<d) insertEdge(i,j+n),insertEdge(j,i+n);
if(map[i][j+n]<d) insertEdge(i,j),insertEdge(j+n,i+n);
if(map[i+n][j]<d) insertEdge(i+n,j+n),insertEdge(j,i);
if(map[i+n][j+n]<d) insertEdge(i+n,j),insertEdge(j+n,i);
}
return Tarjan_SCC();
}
double solve()
{
double ans=min;
while(fabs(max-min)>=eps)
{
double mid=(min+max)/2;
if(check(mid))
{
if(ans<mid) ans=mid;
min=mid;
}
else max=mid;
}
return ans;
}
int main()
{
while(scanf("%d",&n)!=EOF)
{
for(int i=1; i<=n; i++)
{
scanf("%d%d",&q[i].x,&q[i].y);
scanf("%d%d",&q[i+n].x,&q[i+n].y);
}
min=1000000.00,max=-1.0;
for(int i=1; i<=2*n; i++)
for(int j=1; j<=2*n; j++)
{
double l=len(i,j);
if(l>max) max=l;
if(l<min) min=l;
map[i][j]=l;
}
printf("%0.2lf\n",solve()/2);
}
return 0;
}
38

被折叠的 条评论
为什么被折叠?



