답안 #122403

# 제출 시각 아이디 문제 언어 결과 실행 시간 메모리
122403 2019-06-28T07:13:01 Z 윤교준(#2990) 통행료 (APIO13_toll) C++14
16 / 100
5 ms 3200 KB
#include <bits/stdc++.h>
#define rf(x) (x)=0;while(*p<48)p++;while(47<*p)(x)=((x)<<3)+((x)<<1)+(*p++&15);
#define eb emplace_back
#define sz(V) ((int)(V).size())
#define allv(V) ((V).begin()),((V).end())
#define sorv(V) sort(allv(V))
#define univ(V) (V).erase(unique(allv(V)),(V).end())
#define upmax(a,b) (a)=max((a),(b))
#define upmin(a,b) (a)=min((a),(b))
#define INF (0x3f3f3f3f)
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
unsigned char str[10000055], *p=str;

const bool debug = 0;

const int MAXN = 100055;
const int MAXK = 21;

struct DJF {
	DJF() { init(); }
	int ud[MAXN];

	void init() { iota(ud, ud+MAXN, 0); }
	int uf(int i) { return i == ud[i] ? i : (ud[i] = uf(ud[i])); }
	void uf(int a, int b) { ud[uf(b)] = uf(a); }
} djf;

struct EDG {
	EDG(int p, int v, ll sumU, ll sumD, int mxe)
		: p(p), v(v), sumU(sumU), sumD(sumD), mxe(mxe), ign(false), dead(false) {}
	EDG(int p, int v) : p(p), v(v), ign(true), dead(false) {}
	EDG() : ign(false) {}

	int p, v;

	ll sumU, sumD;
	int mxe;

	bool ign, dead;

	int nxt(int i) { return p^v^i; }
	ll sums() { return sumU + sumD; }
	void swp() { swap(p, v); swap(sumU, sumD); }
};

struct GPH {
	GPH() : edgn(0) {}

	vector<int> G[MAXK<<2];
	EDG edg[MAXK*5]; int edgn;
	set<int> PQ[MAXK<<2];
	ll D[MAXK<<2], E[MAXK<<2];
	int prte[MAXK<<2];

	bitset<MAXK<<2> chk;
	int lca(int a, int b) {
		if(a == b) return a;
		chk.reset();
		for(;;) {
			chk[a] = true;
			if(1 == a) break;
			a = edg[prte[a]].p;
		}
		for(;;) {
			if(chk[b]) return b;
			b = edg[prte[b]].p;
		}
	}

	void dfs(int i, int p) {
		for(int e : G[i]) if(!edg[e].dead) {
			int v = edg[e].nxt(i);
			if(v == p) {
				prte[i] = e;
				continue;
			}
			if(edg[e].p != i) edg[e].swp();
			dfs(v, i);
		}
	}
	void dfssum(int i, int p) {
		auto &V = PQ[i];
		E[i] = D[i];
		for(int e : G[i]) if(!edg[e].dead) {
			int v = edg[e].nxt(i);
			if(v == p) {
				prte[i] = e;
				continue;
			}
			if(edg[e].p != i) edg[e].swp();
			dfssum(v, i);
			E[i] += E[v];
			if(!edg[e].ign) E[i] += edg[e].sums();

			auto &T = PQ[v];
			if(edg[e].ign) edg[e].mxe = *T.begin();
			for(int w : T) {
				auto it = V.find(w);
				if(V.end() == it) V.insert(w);
				else V.erase(it);
			}
			T.clear();
		}
	}

	void remove(int v, int e) {
		G[v].erase(find(allv(G[v]), e));
	}

	void goupWithEdge(int a, int c, int &mxe, int &mxei) {
		for(int v = a, e; v != c;) {
			e = prte[v];
			if(!edg[e].ign && mxe < edg[e].mxe) {
				mxe = edg[e].mxe;
				mxei = e;
			}
			v = edg[e].p;
		}
	}

	int addEdge(int a, int b) {
		int c = lca(a, b);
		int mxe = -1, mxei = -1;
		goupWithEdge(a, c, mxe, mxei);
		goupWithEdge(b, c, mxe, mxei);
		if(mxei < 0) return -1;

		D[edg[mxei].p] += edg[mxei].sumU;
		D[edg[mxei].v] += edg[mxei].sumD;
		edg[mxei].dead = true;
		//remove(edg[mxei].p, mxei);
		//remove(edg[mxei].v, mxei);

		edgn++;
		edg[edgn] = EDG(a, b);
		G[a].eb(edgn);
		G[b].eb(edgn);

		//dfs(1, -1);

		return mxei;
	}
	void rollback(int a, int b, int mxei) {
		G[a].pop_back();
		G[b].pop_back();
		edgn--;

		edg[mxei].dead = false;
		D[edg[mxei].p] -= edg[mxei].sumU;
		D[edg[mxei].v] -= edg[mxei].sumD;
	}

	void addEdge(EDG e) {
		edgn++;
		edg[edgn] = e;
		G[e.p].eb(edgn);
		G[e.v].eb(edgn);
	}

	ll getAns(int n) {
		for(int i = 1; i < n; i++) if(edg[i].dead) {
			PQ[edg[i].p].insert(edg[i].mxe);
			PQ[edg[i].v].insert(edg[i].mxe);
		}
		dfssum(1, -1);

		ll ret = 0;
		for(int i = n; i <= edgn; i++) if(edg[i].ign)
			ret += E[edg[i].v] * edg[i].mxe;
		return ret;
	}
};

vector<int> G[MAXN];

vector<int> TV;
vector<pii> TE;
vector<EDG> EDGV;
bitset<MAXN> chkV, chkE;

int prt[17][MAXN];
int prte[MAXN], dep[MAXN], cnt[MAXN], dfo[MAXN];

int A[MAXN], B[MAXN], C[MAXN];
ll D[MAXN];
int E[MAXK], F[MAXK];

ll Ans;
int N, K;


int getI(int v) { return int(lower_bound(allv(TV), v) - TV.begin()) + 1; }

bitset<1<<MAXK> solveDFSchk;
void solveDFS(GPH &gph, int key) {
	solveDFSchk[key] = true;

	upmax(Ans, gph.getAns(sz(TV)));
	for(int i = 0; i < K; i++) {
		if((key & (1<<i)) || solveDFSchk[key | (1<<i)]) continue;
		int ret = gph.addEdge(getI(E[i]), getI(F[i]));
		if(ret < 0) continue;
		solveDFS(gph, key | (1<<i));
		gph.rollback(ret, getI(E[i]), getI(F[i]));
	}

}

void solve() {
	GPH tree;
	for(auto e : EDGV) {
		e.p = getI(e.p);
		e.v = getI(e.v);
		tree.addEdge(e);
	}
	for(int v : TV) tree.D[getI(v)] = D[v];
	tree.dfs(1, -1);

	solveDFS(tree, 0);
}


bool isin(int p, int v) { return dfo[p] <= dfo[v] && dfo[v] < dfo[p] + cnt[p]; }

int lca(int a, int b) {
	if(dep[a] > dep[b]) swap(a, b);
	const int dt = dep[b] - dep[a];
	for(int i = 17; i--;) if(dt & (1<<i))
		b = prt[i][b];
	if(a == b) return a;
	for(int i = 17; i--;) if(prt[i][a] != prt[i][b]) {
		a = prt[i][a];
		b = prt[i][b];
	}
	return prt[0][a];
}

void dfs(int i, int &c) {
	cnt[i] = 1; dfo[i] = ++c;
	for(int e : G[i]) {
		int v = A[e]^B[e]^i;
		if(dep[v]) continue;
		dep[v] = dep[i] + 1;
		prte[v] = e;
		prt[0][v] = i;
		dfs(v, c);
		cnt[i] += cnt[v];
	}
}

void input() {
	fread(str, 1, 10000055, stdin);

	vector<pair<int, pii>> EV;
	int M;

	rf(N) rf(M) rf(K)
	for(int i = 0, a, b, c; i < M; i++) {
		rf(a) rf(b) rf(c)
		EV.eb(c, pii(a, b));
	}
	for(int i = 0; i < K; i++) { rf(E[i]) rf(F[i]) }
	for(int i = 1; i <= N; i++) { rf(D[i]) }

	sorv(EV); M = 0;
	for(auto &e : EV) {
		int a, b, c = e.first;
		tie(a, b) = e.second;
		if(djf.uf(a) == djf.uf(b)) continue;
		djf.uf(a, b);
		M++;
		A[M] = a; B[M] = b; C[M] = c;
		G[a].eb(M);
		G[b].eb(M);
	}
}

void treeCompress() {
	vector<int> V, VT;
	V.eb(1);
	for(int i = 0; i < K; i++) {
		V.eb(E[i]);
		V.eb(F[i]);
	}
	sort(allv(V), [&](int a, int b) { return dfo[a] < dfo[b]; });
	univ(V);

	for(int i = 1, n = sz(V); i < n; i++)
		V.eb(lca(V[i-1], V[i]));
	sort(allv(V), [&](int a, int b) { return dfo[a] < dfo[b]; });
	univ(V);

	for(int v : V) chkV[v] = true;
	TV = V; sorv(TV);

	for(int v : V) {
		for(; !VT.empty() && !isin(VT.back(), v); VT.pop_back());
		if(!VT.empty()) TE.eb(VT.back(), v);
		VT.eb(v);
	}
}

void colorEdges() {
	for(auto &e : TE) {
		int p, v; tie(p, v) = e;
		for(; v != p;) {
			chkE[prte[v]] = true;
			v = prt[0][v];
		}
	}
}

void dfsleaf(int i) {
	for(int e : G[i]) if(e != prte[i]) {
		int v = A[e]^B[e]^i;
		dfsleaf(v);
		if(chkE[e]) continue;
		D[i] += D[v];
		D[v] = 0;
	}
}

void makeEdges() {
	for(auto &ed : TE) {
		int p, v; tie(p, v) = ed;
		ll sumU = 0, sumD = 0;
		int mxe = -1;
		for(int e; v != p;) {
			e = prte[v];
			if(mxe < C[e]) {
				mxe = C[e];
				sumD += sumU;
				sumU = 0;
			}
			v = prt[0][v];
			sumU += D[v];
		}
		sumU -= D[p];
		EDGV.eb(p, ed.second, sumU, sumD, mxe);
	}
}

int main() {
	input();

	if(debug) {
		for(int i = 1; i < N; i++) printf("EDG %d ; %d %d %d\n", i, A[i], B[i], C[i]);
	}

	dep[1] = 1; { int c = 0; dfs(1, c); }
	for(int j = 1; j < 17; j++) for(int i = 1; i <= N; i++)
		prt[j][i] = prt[j-1][prt[j-1][i]];
	
	treeCompress();
	colorEdges();
	dfsleaf(1);
	makeEdges();

	solve();

	cout << Ans << endl;
	return 0;
}

Compilation message

toll.cpp: In function 'void input()':
toll.cpp:254:7: warning: ignoring return value of 'size_t fread(void*, size_t, size_t, FILE*)', declared with attribute warn_unused_result [-Wunused-result]
  fread(str, 1, 10000055, stdin);
  ~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~
# 결과 실행 시간 메모리 Grader output
1 Correct 4 ms 3200 KB Output is correct
2 Correct 5 ms 3200 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 4 ms 3200 KB Output is correct
2 Correct 5 ms 3200 KB Output is correct
3 Incorrect 4 ms 3200 KB Output isn't correct
4 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Correct 4 ms 3200 KB Output is correct
2 Correct 5 ms 3200 KB Output is correct
3 Incorrect 4 ms 3200 KB Output isn't correct
4 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Correct 4 ms 3200 KB Output is correct
2 Correct 5 ms 3200 KB Output is correct
3 Incorrect 4 ms 3200 KB Output isn't correct
4 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Correct 4 ms 3200 KB Output is correct
2 Correct 5 ms 3200 KB Output is correct
3 Incorrect 4 ms 3200 KB Output isn't correct
4 Halted 0 ms 0 KB -