Topcoder 2016 TCO Algorithm Algo Semifinal 1 - Division I, Level Three ColorfulPath 题解
Topcoder 2016 TCO Algorithm Algo Semifinal 1 - Division I, Level Three ColorfulPath 题解
最短路转对偶图最小割!
这样颜色的限制就转变成必须都在割的一侧。
但是这个树形图和一般图有一些不同的地方,就是如果儿子属于\(s\),那么它的父亲也要属于\(s\)。这样才能保证一条合法的路径。
操作起来也非常简单,直接连一条儿子到父亲的\(+\infty\)的边即可。
const int MAXN=2500;
int n;
int c[MAXN];
bool havefa[MAXN];
vector<pair<mp,int> > edges;
bool cmp(pair<mp,int> A,pair<mp,int> B){
    return A.FIR.SEC-A.FIR.FIR<B.FIR.SEC-B.FIR.FIR;
}
vector<pair<mp,mp> > g[MAXN];
vector<int> eachcol[MAXN];
int dfs(int now,int l=1,int r=n){
    if(l==r-1) return t;
	sort(ALL(g[now]));
    for(auto it:g[now]){
		if(it.FIR.SEC!=r){
			eachcol[c[it.FIR.SEC]].PB(now);
		}
	}
    for(auto it:g[now]){
        int v=dfs(it.SEC.SEC,it.FIR.FIR,it.FIR.SEC);
        make_edge(now,v,it.SEC.FIR);
		make_edge(v,now,INF);
    }
    return now;
}
class ColorfulPath{
    public:
        int shortestPath(vector<int> a, vector<int> b, vector<int> cost, vector<int> color){
            n=color.size()+2;
            rb(i,2,n-1) c[i]=color[i-2];
            map<mp,int> best_e;
            a.PB(0);b.PB(n-1);cost.PB(INF-1);
            rb(i,0,n-2) a.PB(i),b.PB(i+1),cost.PB(INF-1);
            rep(i,a.size()){
                int u,v;
                tie(u,v)=II(a[i]+1,b[i]+1);
                if(best_e.find(II(u,v))==best_e.end()||best_e[II(u,v)]>cost[i]){
                    best_e[II(u,v)]=cost[i];
                }
            }
            for(auto ite=best_e.begin();ite!=best_e.end();ite++){
                edges.PB(*ite);
            }
            sort(ALL(edges),cmp);
            rep(i,edges.size()){
                rep(j,i){
                    if(edges[j].FIR.SEC<=edges[i].FIR.SEC&&edges[j].FIR.FIR>=edges[i].FIR.FIR&&!havefa[j]){
                        havefa[j]=1;
                        g[i+1].PB(II(edges[j].FIR,II(edges[j].SEC,j+1)));
                    }
                }
            }
            make_edge(s,dfs(edges.size()),edges.back().SEC);
            rb(i,1,1000){
                for(auto it:eachcol[i]) for(auto itt:eachcol[i]) make_edge(it,itt,INF);
            }
            int D=Dinic();
            if(D>1000000000) D=-1;
            return D;
        }
};
 
                    
                     
                    
                 
                    
                
 
                
            
         
         浙公网安备 33010602011771号
浙公网安备 33010602011771号