Example #1
0
	bool propagate() {
 //fprintf(stderr, "AllDiffDomain::propagate()\n");
		// Edmonds-Karp, loop to find and augment a path
		while (1) {
			int var;
			int val;

			// visit source
			queue_tail = &queue;
			for (int i = 0; i < sz; ++i)
				if (var_nodes[i].match < 0) {
					*queue_tail = i;
					queue_tail = &var_nodes[i].next;
				}
			*queue_tail = -1;
			for (int i = 0; i < range; ++i)
				val_nodes[i].mark = false;

			// visit vars, also subsume visit of vals
			while (queue >= 0) {
				queue_tail = &queue;
				for (var = queue; var >= 0; var = var_nodes[var].next)
					for (typename IntView<U>::iterator i = x[var].begin(); i != x[var].end(); ++i) {
						val = *i;
						if (!val_nodes[val].mark) {
							assert(val != var_nodes[var].match);
							int next_var = val_nodes[val].match;
							if (next_var < 0)
								goto augment;

							val_nodes[val].mark = true;
							val_nodes[val].next = var;
							*queue_tail = next_var;
							queue_tail = &var_nodes[next_var].next;
						}
					}
				*queue_tail = -1;
			}

			// no more augmenting paths
			break;

		augment:
			// found an augmenting path
			while (1) {
				int parent_val = var_nodes[var].match;
				val_nodes[val].match = var;
				var_nodes[var].match = val;
				if (parent_val < 0)
					break;
				val = parent_val;
				var = val_nodes[val].next;
			}
		}
 //fprintf(stderr, "match");
 //for (int i = 0; i < sz; ++i)
 // fprintf(stderr, " %d", var_nodes[i].match);
 //fprintf(stderr, "\n");

		index = 0;
		stack = -1;
		for (int i = 0; i < sz + range; ++i)
			var_nodes[i].mark = false;
		for (int i = 0; i < sz; ++i)
			if (!var_nodes[i].mark && !tarjan(i))
				return false;

		return true;
	}
Example #2
0
int main(){
	part = n;
	for(int i = 1; i <= n; ++i) if(!dfn[i]) tarjan(i, part + 1);
}
Example #3
0
int main() {
	freopen("F.in", "r", stdin);
	scanf("%d", &T);
	for (int cs = 1; cs <= T; cs++) {
		scanf("%d%d", &n, &m);
		nColor = tot = top = nPart = 0;
		std::fill(h + 1, h + n + m + 1, t = 0);
		std::fill(dfn + 1, dfn + n + m + 1, 0);
		std::fill(low + 1, low + n + m + 1, 0);
		std::fill(cut + 1, cut + n + m + 1, false);

		for (int i = 1; i <= n; i++) scanf("%d", w + i);
		for (int i = 1; i <= m; i++) {
			scanf("%d%d", &r[i].x, &r[i].y);
			addEdge(r[i].x, r[i].y);
		}
		std::fill(belong + 1, belong + n + 1, 0);
		for (int i = 1; i <= n; i++) {
			if (belong[i]) continue;
			static int q[MAXN];
			nPart++;
			int left = 0, right = 0;
			belong[q[++right] = i] = nPart;
			while (left < right) {
				left++;
				for (int i = h[q[left]]; i; i = e[i].next) {
					if (belong[e[i].node]) continue;
					belong[q[++right] = e[i].node] = nPart;
				}
			}
		}
		std::fill(size + 1, size + n + 1, 0);
		std::fill(prod + 1, prod + nPart + 1, 1);
		for (int i = 1; i <= n; i++) {
			prod[belong[i]] = 1ll * prod[belong[i]] * w[i] % MOD;
			size[belong[i]]++;
		}

		std::fill(h + 1, h + n + m + 1, t = 0);
		for (int i = 1; i <= m; i++) {
			addEdge(r[i].x, n + i);
			addEdge(r[i].y, n + i);
		}

		for (int i = 1; i <= n + m; i++) {
			if (dfn[i]) continue;
			cut[i] = tarjan(i) > 1;
		}	

		std::vector<int> dis;
		for (int i = 1; i <= n + m; i++) {
			if (i <= n && size[belong[i]] == 1) {
				col[i] = ++nColor;
				dis.push_back(col[i]);
				continue;
			}
			if (cut[i]) col[i] = ++nColor;
			dis.push_back(col[i]);
		}
		std::sort(dis.begin(), dis.end());
		dis.erase(std::unique(dis.begin(), dis.end()), dis.end());
		for (int i = 1; i <= n + m; i++) {
			col[i] = std::lower_bound(dis.begin(), dis.end(), col[i]) - dis.begin() + 1;
		}
		nColor = dis.size();

		std::fill(prodBlock + 1, prodBlock + nColor + 1, 1);
		for (int i = 1; i <= n; i++) {
			prodBlock[col[i]] = 1ll * prodBlock[col[i]] * w[i] % MOD;
		}

		std::fill(h + 1, h + nColor + 1, t = 0);
		for (int i = 1; i <= m; i++) {
			if (col[r[i].x] != col[n + i]) {
				addEdge(col[r[i].x], col[n + i]);
				//printf("AddEdge(%d, %d)\n", col[r[i].x], col[r[i].y]);
			}
			if (col[r[i].y] != col[n + i]) {
				addEdge(col[r[i].y], col[n + i]);
				//printf("AddEdge(%d, %d)\n", col[r[i].x], col[r[i].y]);
			}
		}

		int answer = 0, total = 0;
		for (int i = 1; i <= nPart; i++) {
			total = (total + prod[i]) % MOD;
		}
		std::fill(v + 1, v + nColor + 1, false);
		for (int i = 1; i <= nColor; i++) {
			if (v[i]) continue;
			dfs(i);
		}
		for (int i = 1; i <= n; i++) {
			if (size[belong[i]] == 1) {
				long long tmp = (total - prod[belong[i]]) % MOD;
				answer = (answer + 1ll * i * tmp % MOD) % MOD;
				continue;
			}
			if (!cut[i]) {
				long long tmp = (total - prod[belong[i]]) % MOD;
				tmp = (tmp + 1ll * prod[belong[i]] * fpm(w[i], MOD - 2) % MOD) % MOD;
				answer = (answer + 1ll * i * tmp % MOD) % MOD;
			} else {
				long long tmp = prod[belong[i]];
				tmp = 1ll * tmp * fpm(subProd[col[i]], MOD - 2) % MOD;
				tmp = (tmp + subSum[col[i]]) % MOD;
				tmp = (tmp + total - prod[belong[i]]) % MOD;
				answer = (answer + 1ll * i * tmp % MOD) % MOD;
			}
		}
		answer = (answer % MOD + MOD) % MOD;
		printf("%d\n", answer);
	}
	return 0;
}
	//求有向图的强联通分量
	void find_scc(int n){
		dfs_clock = scc_cnt = 0;
		for(int i = 0;i<n;i++) sccno[i] = pre[i] = 0;
		for(int i = 0;i<n;i++)
			if(!pre[i]) tarjan(i);
	}
Example #5
0
 std::vector<int> get_bcc(){
     for (int i=1;i<=N;i++) if (!chk[i]) tarjan(i);
     return bcc;
 }
Example #6
0
int main()  {
	/*****/
	for(int i = 1;i <= n;i++)
		if(!dfn[i]) tarjan(i);
}
Example #7
0
int main(){
    while(~scanf("%d %d", &n, &m)){
        if(n==0 && m==0) break;
        init();
        while(m--){
            int u, v;
            scanf("%d %d", &u, &v);
            add(u, v, head, edge);
            add(v, u, head, edge);
        }
        for(int i = 1; i <= n; i++){
            if(!dfn[i]) tarjan(i, -1);
        }
        cnt = 0;
        for(int u = 1; u <= n; u++){
            for(int i = head[u]; i != -1; i = edge[i].next){
                int v = edge[i].v;
                if(bccno[u] != bccno[v]){
                    add(bccno[u], v, head1, edge1);
                }
            }
        }
        d[1] = 0;
        dfs(1, 1);
        scanf("%d", &m);
        while(m--){
            int u, v, w;
            scanf("%d %d %d", &u, &v, &w);
            int uu = bccno[u], vv = bccno[v], ww = bccno[w];
            int uv = lca(uu, vv), uw = lca(uu, ww), vw = lca(vv, ww);
            if(u==v){
                if(u==w) puts("Yes");
                else puts("No");
            }
            else if(u==w || v==w) puts("Yes");
            else if(uu==vv){
                if(uu==ww) puts("Yes");
                else puts("No");
            }
            else if(uu==ww){
                int ret;
                if(uv==uu){
                    vv = swim(vv, ww);
                    ret = judge(vv, u);
                }
                else ret = judge(p[uu][0], u);
                if(ret!=u) puts("Yes");
                else puts("No");
            }
            else if(vv==ww){
                int ret;
                if(uv==vv){
                    uu = swim(uu, ww);
                    ret = judge(uu, v);
                }
                else ret = judge(p[vv][0],v);
                if(ret!=v) puts("Yes");
                else puts("No");
            }
            else{
                if(uv==uw && vw==ww){
                    int ret1, ret2;
                    vv = swim(vv, ww);
                    ret1 = judge(vv, w);
                    if(uv==ww){
                        uu = swim(uu, ww);
                        ret2 = judge(uu, w);
                    }
                    else ret2 = judge(p[ww][0],w);
                    if(ret1!=w && ret2!=w && ret1==ret2) puts("No");
                    else puts("Yes");
                }
                else if(uv==vw && uw==ww){
                    int ret1, ret2;
                    uu = swim(uu, ww);
                    ret1 = judge(uu, w);
                    if(uv==ww){
                        vv = swim(vv, ww);
                        ret2 = judge(vv, w);
                    }
                    else ret2 = judge(p[ww][0],w);
                    if(ret1!=w && ret2!=w && ret1==ret2) puts("No");
                    else puts("Yes");
                }
                else puts("No");
            }
        }
    }
    return 0;
}
Example #8
0
// merge Strongly Connected Component
// return vertex map between old vertex and corresponding new merged vertex
void GraphUtil::mergeSCC(Graph& g, int* on, vector<int>& reverse_topo_sort) {
	vector<int> sn;
	hash_map< int, pair<int, int> > order;
	int ind = 0;
	multimap<int, int> sccmap;	// each vertex id correspond with a scc num 
	int scc = 0;
	int vid;
	int origsize = g.num_vertices();
//	cout << " inside MergeSCC "<< endl;	
	for (int i = 0; i < origsize; i++) {
		vid = i;
		if (g[vid].visited)
			continue;
		tarjan(g, vid, ind, order, sn, sccmap, scc);
	}
//	cout << " inside MergeSCC after tarjan "<< endl;	
	// no component need to merge
	if (scc == origsize) {
		for (int i = 0; i < origsize; i++)
			on[i] = i;
		// topological sort
		topological_sort(g, reverse_topo_sort);
		// update graph's topological id
		for (int i = 0; i < reverse_topo_sort.size(); i++)
			g[reverse_topo_sort[i]].topo_id = reverse_topo_sort.size()-i-1;

		return;
	}


	hash_map<int, vector<int> > inlist, outlist;
	g.extract(inlist, outlist);
	
	multimap<int,int>::iterator mit;
	mit = sccmap.begin();
	int num_comp;
	int maxid = g.num_vertices()-1;
	while (mit != sccmap.end()) {
		num_comp = mit->first;
		
		if (++sccmap.lower_bound(num_comp) == sccmap.upper_bound(num_comp)) {
			on[mit->second] = mit->second;
			++mit;
			continue;
		}

		maxid++;
		inlist[maxid] = vector<int>();
		outlist[maxid] = vector<int>();
		
		for (; mit != sccmap.upper_bound(num_comp); ++mit) {
			on[mit->second] = maxid;

			vector<int> vec = inlist[mit->second];
			vector<int>::iterator vit, vit1;
			vector<int> vec1;
			bool hasEdge = false;

			// copy all incoming edges
			for (vit = vec.begin(); vit != vec.end(); vit++) {
				hasEdge = false;
				vec1 = outlist[*vit];
				for (vit1 = vec1.begin(); vit1 != vec1.end(); vit1++) {
					if (*vit1 == maxid) {
						hasEdge = true;
						break;
					}
				}
				if (!hasEdge && (*vit != maxid)) {
					inlist[maxid].push_back(*vit);
					outlist[*vit].push_back(maxid);
				}
			}

			// copy all outgoing edges
			vec = outlist[mit->second];
			for (vit = vec.begin(); vit != vec.end(); vit++) {
				hasEdge = false;
				vec1 = inlist[*vit];
				for (vit1 = vec1.begin(); vit1 != vec1.end(); vit1++)
					if (*vit1 == maxid) {
						hasEdge = true;
						break;
					}
				if (!hasEdge && (*vit != maxid)) {
					outlist[maxid].push_back(*vit);
					inlist[*vit].push_back(maxid);
				}
			}
			
			// delete old vertex
			vec = inlist[mit->second];
			for (vit = vec.begin(); vit != vec.end(); vit++) {
				for (vit1 = outlist[*vit].begin(); vit1 != outlist[*vit].end(); )
					if (*vit1 == mit->second)
						outlist[*vit].erase(vit1);
					else
						vit1++;
			}
			vec = outlist[mit->second];
			for (vit = vec.begin(); vit != vec.end(); vit++) {
				for (vit1 = inlist[*vit].begin(); vit1 != inlist[*vit].end(); )
					if (*vit1 == mit->second)
						inlist[*vit].erase(vit1);
					else
						vit1++;
			}
			outlist.erase(mit->second);
			inlist.erase(mit->second);
		}
	}			

	g = Graph(inlist, outlist);
	
	// topological sort
	topological_sort(g, reverse_topo_sort);
	// update graph's topological id
	for (int i = 0; i < reverse_topo_sort.size(); i++)
		g[reverse_topo_sort[i]].topo_id = reverse_topo_sort.size()-i-1;

	// update index map
	hash_map<int,int> indexmap;
	hash_map<int, vector<int> >::iterator hit;
	int k;
	for (hit = outlist.begin(), k=0; hit != outlist.end(); hit++, k++) {
		indexmap[hit->first] = k;
	}
	for (k = 0; k < origsize; k++)
		on[k] = indexmap[on[k]];

/*
	cout << "Index Map" << endl;
	for (int i = 0; i < origsize; i++)
		cout << on[i] << " ";
	cout << endl;
	cout << "roots: " << g.getRoots().size() << endl;
*/
}