最近的几次比赛
NOIP模拟题 2015.8.1 T2

UOJ #134

HJWJBSR posted @ 2015年8月11日 14:48 in 题解 , 496 阅读

题面:给定一张无向图,然后将其中一些边定向,要求将剩下的无向边也定向,使得原无向图中的连通块在变成有向图之后还是在同一个强连通分量。(n,m<=5000)

题解:好神啊,考场上面并没有想出来,连60分暴力都斜挂了= =

有一个性质:在当前还没定向完的图中对于每条边的两个点u和v要不就u不通过这条边可以到达v,要不就是v可以不通过这条边可以到达u。然后就可以暴力遍历整张图然后判断是哪种情况就可以定向了。

看完证明感觉还是很有道理,移步这♂里♂

#include <iostream>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <algorithm>
using namespace std;
#define N 5050
int b[N][N],d[N],n,m,fi[N],c[N*2][2],ss=1,ln[N][3],now;
inline int Read()
 {
    int x=0;char y;
    do y=getchar(); while (y<'0'||y>'9');
    do x=x*10+y-'0',y=getchar(); while (y>='0'&&y<='9');
    return x;
 }
inline void Line(int x,int y)
 {c[++ss][0]=y;c[ss][1]=fi[x];fi[x]=ss;b[x][y]++;}
void DFS(int x)
 {
    d[x]=now;
    for (int i=fi[x];i;i=c[i][1])
     if (b[x][c[i][0]]&&d[c[i][0]]!=now) DFS(c[i][0]);
 }
int main()
 {
    n=Read();m=Read();
    for (int i=1;i<=m;i++)
     {
        ln[i][0]=Read();ln[i][1]=Read();ln[i][2]=Read();
        Line(ln[i][0],ln[i][1]);
        if (!ln[i][2]) Line(ln[i][1],ln[i][0]);
     }
    for (int i=1;i<=m;i++)
     if (!ln[i][2])
      {
         now++;b[ln[i][0]][ln[i][1]]--;
         DFS(ln[i][0]);b[ln[i][0]][ln[i][1]]++;
         if (d[ln[i][1]]==now)
          b[ln[i][0]][ln[i][1]]--,puts("1");else
          b[ln[i][1]][ln[i][0]]--,puts("0");
      } else puts("0");
    return 0;
 }

登录 *


loading captcha image...
(输入验证码)
or Ctrl+Enter