bzoj2330

簡直做了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);
	}
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章