您的位置:首页 > 其它

bzoj2330

2016-03-10 18:29 239 查看
龟儿子(划掉)。。简直做了3个小时

我还是太辣鸡了。

不过我居然没考虑到差分约束(明明是你记不到了233

黑算法乱搞

tarjan 拓扑排序

黑过去了

#include <queue>
#include <cstdio>
#include <cstring>
#include <algorithm>
#define LL long long
using namespace std;
LL n,k;

LL leadto1[100010];
LL leadto2[100010];
LL pnt,pnt1;

LL father[100010];

struct ori_edge {
LL x,u,v;
bool operator < (const ori_edge &b)const {
return x < b.x;
}
}E[100010];

struct edge {
LL u,v,next;
}e[100010];
LL cnt,head[100010];

LL read_int () {
char c = getchar();
LL re = 0;
for(;c > '9' || c < '0';c = getchar());
for(;c >= '0' && c <= '9';c = getchar())
re = re * 10 + c - '0';
return re;
}

void pre () {
n = read_int();
k = read_int();
for(LL i = 1;i <= k;++i) {
E[i].x = read_int();
if(E[i].x == 2) {
E[i].x = 3;
E[i].u = read_int();
E[i].v = read_int();
}
else {
if(E[i].x == 3) {
E[i].x = 2;
E[i].v = read_int();
E[i].u = read_int();
}
else {
if(E[i].x == 4) {
E[i].x = 3;
E[i].v = read_int();
E[i].u = read_int();
}
else {
if(E[i].x == 5) {
E[i].x = 2;
E[i].u = read_int();
E[i].v = read_int();
}
else {
E[i].u = read_int();
E[i].v = read_int();
}
}
}
}
}
sort(E + 1,E + 1 + k);
}

LL find (LL u) {
if(father[u] == u)
return u;
return father[u] = find(father[u]);
}

void adde (LL u,LL v) {
e[++cnt].u = u;
e[cnt].v = v;
e[cnt].next = head[u];
head[u] = cnt;
}

LL co,fk;
void step1 () {
for(LL i = 1;i <= n;++i)
father[i] = i;
for(co = 1;E[co].x == 1;++co)
if(find(E[co].u) != find(E[co].v))
father[find(E[co].u)] = find(E[co].v);
for(LL i = 1;i <= n;++i)
if(leadto1[find(i)])
leadto1[i] = leadto1[find(i)];
else leadto1[find(i)] = leadto1[i] = ++pnt;

fk = co;
memset(head,-1,sizeof head);
for(;E[co].x == 2;++co) {
if(leadto1[E[co].u] != leadto1[E[co].v])
adde(leadto1[E[co].u],leadto1[E[co].v]);
}
}

LL idx,dfn[100010],low[100010],vis[100010],ins[100010];
LL st[100010],tp;

void tarjan (LL u,LL flg) {
low[u] = dfn[u] = ++idx;

for(LL i = head[u];i != -1;i = e[i].next) {
LL v = e[i].v;
if(!(vis[v] == 0 || vis[v] == flg))
continue;
vis[v] = flg;
if(dfn[v] && ins[v]) {
low[u] = min(dfn[v],low[u]);
}
else {
if(!dfn[v]) {
ins[v] = 1;
st[++tp] = v;
tarjan(v,flg);
low[u] = min(low[u],low[v]);
}
}
}

if(dfn[u] == low[u]) {
++pnt1;
while(tp) {
leadto2[st[tp--]] = pnt1;
ins[st[tp + 1]] = 0;
if(dfn[st[tp + 1]] == low[st[tp + 1]])
break;
}
}
}

struct edge1 {
LL v,x,next;
}ee[100010];

void adde1 (LL u,LL v,LL x) {
ee[++cnt].v = v;
ee[cnt].x = x;
ee[cnt].next = head[u];
head[u] = cnt;
}

void step2 () {
LL flg = 0;
for(LL i = 1;i <= pnt;++i) {
if(!dfn[i]) {
st[tp = 1] = i;
ins[i] = 1;
vis[i] = ++flg;
tarjan(i,flg);
}
}

memset(head,-1,sizeof head);
cnt = 0;
for(;fk <= k;++fk)
if(leadto2[leadto1[E[fk].u]] != leadto2[leadto1[E[fk].v]])
adde1(leadto2[leadto1[E[fk].u]],leadto2[leadto1[E[fk].v]],E[fk].x);
else {
if(E[fk].x == 3) {
printf("-1\n");
exit(0);
}
}
}

LL in[100010];
queue<LL>q;
LL ans[100010];
LL cc;
void step3 () {
for(LL i = 1;i <= cnt;++i)
++in[ee[i].v];
for(LL i = 1;i <= pnt1;++i)
if(!in[i]) {
q.push(i);
ans[i] = 1;
}

while(!q.empty()) {
LL u = q.front();
q.pop();
++cc;

for(LL i = head[u];i != -1;i = ee[i].next) {
LL v = ee[i].v;

--in[v];
if(ee[i].x == 2) {
if(!(ans[v] >= ans[u]))
ans[v] = ans[u];
}
else {
if(!(ans[v] > ans[u]))
ans[v] = ans[u] + 1;
}
if(!in[v]) {
q.push(v);

}
}
}
}

int main () {
pre();
step1();
step2();
step3();
if(cc != pnt1)
printf("-1\n");
else {
LL hehe = 0;
for(LL i = 1;i <= n;++i)
hehe += ans[leadto2[leadto1[i]]];
printf("%lld\n",hehe);
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: