제출 #224154

#제출 시각아이디문제언어결과실행 시간메모리
224154oolimryOlympic Bus (JOI20_ho_t4)C++14
16 / 100
114 ms7144 KiB
#include <bits/stdc++.h>

using namespace std;
long long inf = (1LL << 56LL);

typedef pair<long long, long long> ii;
typedef vector<int> vi;
vector<ii> adj[205];
vector<ii> adjR[205];
long long dis[205];
long long dis1[205];
long long disn[205];
long long dis1R[205];
long long disnR[205];

int n, m; 

long long dij(int s, int t){
	fill(dis, dis + (n+3), inf);
	
	priority_queue<ii, vector<ii>, greater<ii> > dtr; /// use greater<int>
	dtr.push(ii(0,s));
    dis[s] = 0;
    ///first is minpath, second is vertex
    while(!dtr.empty()){
        ii cur = dtr.top();
        dtr.pop();
        for(int j = 0;j < (int) adj[cur.second].size();j++){
            ii nei = adj[cur.second][j];
            if(nei.first + cur.first < dis[nei.second]){
                dis[nei.second] = nei.first + cur.first;
                dtr.push(ii(dis[nei.second],nei.second));
            }
        }
    }
    return dis[t];
}

long long dijR(int s, int t){
	fill(dis, dis + (n+3), inf);
	
	priority_queue<ii, vector<ii>, greater<ii> > dtr; /// use greater<int>
	dtr.push(ii(0,s));
    dis[s] = 0;
    ///first is minpath, second is vertex
    while(!dtr.empty()){
        ii cur = dtr.top();
        dtr.pop();
        for(int j = 0;j < (int) adjR[cur.second].size();j++){
            ii nei = adjR[cur.second][j];
            if(nei.first + cur.first < dis[nei.second]){
                dis[nei.second] = nei.first + cur.first;
                dtr.push(ii(dis[nei.second],nei.second));
            }
        }
    }
    return dis[t];
}

struct edge{
	long long u; long long v; long long c; long long d;
};
vector<edge> edges;

void prin(long long ans){
	if(ans >= inf) ans = -1;
	cout << ans;
	exit(0);
}

void subtask1(){
	long long ans = dij(1, n)+ dij(n, 1);
	for(int i = 0;i < m;i++){
		for(int i = 1;i <= n;i++) adj[i].clear();
		
		long long res = 0;
		for(int j = 0;j < m;j++){
			edge e = edges[j];
			if(i == j){
				adj[e.v].push_back(ii(e.c,e.u));
				res += e.d;
			}
			else adj[e.u].push_back(ii(e.c,e.v));
		}
		//cout << dij(1,n) + dij(n,1) + res << "\n";
		ans = min(ans, dij(1,n) + dij(n,1) + res);
	}
	
	prin(ans);
}

map<ii, int> LIGHT;

struct node{
    vi adj;
    vi bac;
    bool vis = false;
    int sccNo = -1;
    int value = 0;
};

node g1[205];

stack<int> order;
void dfs(int i){
    if(g1[i].vis) return;
    g1[i].vis = true;
    for(int j = 0;j < (int) g1[i].adj.size();j++){
        dfs(g1[i].adj[j]);
    }
    order.push(i);
}

vector<int> scc;
void dfs2(int i){
    if(g1[i].vis) return;
    g1[i].vis = true;
    for(int j = 0;j < (int) g1[i].bac.size();j++){
        dfs2(g1[i].bac[j]);
    }
    scc.push_back(i);
}


vector<node> dag;
vector<node> gad;

vector<int> ADJ[205];
vector<int> JDA[205];
bool SB[205];
bool TB[205];

ii memo[205];
long long dp(int u, int s){
	if(u == s) return 1;
	if(memo[u] != ii(0,0)) return memo[u].first;
	ii res = ii(0,0);
	for(int v : JDA[u]){
		long long x = dp(v, s);
		if(x != 0){
			res.first += x;
			res.second = v;
		}
	}
	memo[u] = res;
	return res.first;
}

void subtask3(){
	for(edge e : edges){
		g1[e.u].adj.push_back(e.v);
		g1[e.v].bac.push_back(e.u);
	}
	
	for(int i = 1;i <= n;i++){
        dfs(i);
    }
    for(int i = 1;i <= n;i++){
        g1[i].vis = false;
    }
    int c = 0;
    while(!order.empty()){
        int u = order.top();
        order.pop();
        if(g1[u].vis) continue;
        scc.clear();
        dfs2(u);
        for(int i = 0;i < (int) scc.size();i++){
            //cout << scc[i] << " ";
            g1[scc[i]].sccNo = c;
        }
        c++;
        node nn;
        nn.value = scc.size();
        dag.push_back(nn);
        //cout << "\n";
    }
    typedef pair<int,int> ii;
    map<ii, int> edges;
    for(int i = 1;i <= n;i++){
        for(int j = 0;j <(int) g1[i].adj.size();j++){
            int v = g1[i].adj[j];
            if(g1[i].sccNo != g1[v].sccNo){
				ii x = ii(g1[i].sccNo,g1[v].sccNo);
                if(edges.find(x) == edges.end()) edges[x] = LIGHT[ii(i,v)];
                else edges[x] = min(edges[x], LIGHT[ii(i,v)]);
            }
        }
    }
    for(int i = 0;i < dag.size();i++){
		dag[i].adj.clear();
	}
	
    //cout << "\nedges\n";
    for(auto a : edges){
        ADJ[a.first.first].push_back(a.first.second);
        JDA[a.first.second].push_back(a.first.first);
        //cout << a.first.first << " " << a.first.second << "\n";
    }
    
    int s = 1, t = n;
    if(dij(s,t) < inf && dij(t,s) < inf){
		prin(0);
	}
	
    
    if(dij(s, t) >= inf){
		swap(s,t);
	}
	if(dij(s,t) >= inf) prin(inf);
	
	long long ans = inf;
	
	//cout << "\nbfs\n";
	//cout << g1[t].sccNo << ", " << g1[s].sccNo << "\n";
	queue<int> bfs;
	
	int S = g1[s].sccNo, T = g1[t].sccNo;
	
	bfs.push(T);
	while(!bfs.empty()){
		int u = bfs.front();bfs.pop();
		if(TB[u]) break;
		//cout << "TB: " << u << "\n";
		TB[u] = true;
		for(int v : ADJ[u]){
			bfs.push(v);
		}
		
	}
	
	bfs.push(S);
	while(!bfs.empty()){
		int u = bfs.front();bfs.pop();
		if(SB[u]) break;
		SB[u] = true;
		for(int v : JDA[u]){
			bfs.push(v);
		}
	}
	
	//for(int i = 0;i < (int) dag.size();i++){
	//	cout << TB[i] << " " << SB[i] << "\n";
	//}
	
	dp(T, S);
	//cout << memo[T].first << " " << memo[T].second << "\n"; 
	set<ii> banned;
	if(memo[T].first == 1){
		int u = T;
		while(u != S){
			int v = memo[T].second;
			banned.insert(ii(v,u));
			u = v;
		}
	}
	for(auto a : edges){
		int u = a.first.first; int v = a.first.second;
        if(SB[u] && TB[v] && banned.find(ii(u,v)) == banned.end()){
			ans = min(ans, (long long) a.second);
			//cout << u << " " << v << " " << a.second << "\n";
		}
    }
	   
	prin(ans);
	///try to make a path from t to e
}

int main(){
	//freopen("i.txt","r",stdin);
	ios_base::sync_with_stdio(false);
	cin.tie(0);
	
	bool ST3 = true;
	cin >> n >> m;
	for(int i = 0;i < m;i++){
		long long u, v, c, d; cin >> u >> v >> c >> d;
		edges.push_back({u,v,c,d});
		adj[u].push_back(ii(c,v));
		adjR[v].push_back(ii(c,u));
		if(c != 0) ST3 = false;
		
		if(LIGHT.find(ii(u,v)) == LIGHT.end()) LIGHT[ii(u,v)] = d;
		else{
			LIGHT[ii(u,v)] = min( (long long) LIGHT[ii(u,v)], (long long) d);
		}
	}
	
	if(m <= 1000) subtask1();
	if(ST3) subtask3();
	else{
	
		dij(1,n);
		for(int i = 1;i <= n;i++) dis1[i] = dis[i];
		
		dij(n,1);
		for(int i = 1;i <= n;i++) disn[i] = dis[i];
		
		dijR(1,n);
		for(int i = 1;i <= n;i++) dis1R[i] = dis[i];
		
		dijR(n,1);
		for(int i = 1;i <= n;i++) disnR[i] = dis[i];
		
		long long ans = dis1[n] + disn[1];
		for(edge e : edges){
			///edge goes v -> u
			ans = min(ans, e.d + dis1[n] + disn[e.v] + dis1R[e.u] + e.c);
			ans = min(ans, e.d + disn[1] + dis1[e.v] + disnR[e.u] + e.c);
			ans = min(ans, e.d + dis1[e.v] + disnR[e.u] + disn[e.v] + dis1R[e.u] + 2 * e.c);
		}
		
		prin(ans);
	}
}

컴파일 시 표준 에러 (stderr) 메시지

ho_t4.cpp: In function 'void subtask3()':
ho_t4.cpp:190:21: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
     for(int i = 0;i < dag.size();i++){
                   ~~^~~~~~~~~~~~
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...