难题集

loj10132. 「一本通 4.4 例 3」异象石

loj10133. 「一本通 4.4 例 4」次小生成树

#include<cstdio>
#include<iostream>
#include<vector>
#include<string>
#include<algorithm>
#include<queue>
#include<cstring>
using namespace std;
const int maxn = 100010;
inline void qread(int &x){
    x = 0;
    register int ch = getchar();
    while(ch < '0' || ch > '9')    ch = getchar();
    while(ch >= '0' && ch <= '9'){
        x = 10 * x + ch - 48;
        ch = getchar();
    }
}
int n, m;
struct zmap{
    int N;
    vector<int> G[maxn];
    vector<int> W[maxn];
}m1, m2;
void make(){
    qread(n);
    qread(m);
    m1.N = n;
    for(int i=1; i<=m; ++i){
        int x, y, z;
        qread(x), qread(y), qread(z);
        m1.G[x].push_back(y);
        m1.G[y].push_back(x);
        m1.W[x].push_back(z);
        m1.W[y].push_back(z);
    }
}
struct node{
    int to;
    int dist;
    int from;
};
class cmp{
    public:
        bool operator ()(node A, node B){
            return A.dist > B.dist;
        }
};
node make_node(int a, int b,int c){
        node t;
        t.to = a;
        t.dist = b;
        t.from = c;
        return t;
}
int dist[maxn];
int vst[maxn];
long long ans;
priority_queue<node, vector<node>, cmp>qu; 
void prim(){
    memset(dist, 0x3f, sizeof(dist));
    dist[1] = 0;
    vst[0] = 1;
    qu.push(make_node(0, 1, 0));
    for(int i=1, t=1, f; i<=n; ++i){
        while(vst[t]){
            t = qu.top().to;
            f = qu.top().from;
            qu.pop();
        }
        ans += dist[t];
        vst[t] = 1;
        if(t - 1){
            m2.G[f].push_back(t);
            m2.G[t].push_back(f);
            m2.W[f].push_back(dist[t]);
            m2.W[t].push_back(dist[t]);
        }
        for(int j=0; j<m1.G[t].size(); ++j){
            if(!vst[m1.G[t][j]] && m1.W[t][j] < dist[m1.G[t][j]]){
                dist[m1.G[t][j]] = m1.W[t][j];
                qu.push(make_node(m1.G[t][j], m1.W[t][j], t));
            }    
        }
    }
};
void solve(){
    for(int i=2; i<=n; ++i)
        llog[i] = llog[i >> 1] + 1;
    dfs(1);
    for(int k=1; k<=llog[n]; ++k)
        for(int i=1; i <= n; ++i)
            g[i][k] = g[g[i][k-1]][k-1];
    for(int k=1; k<=llog[n]; ++k)
        for(int i=1; i <= n; ++i)
            h[i][k] = max(h[i][k-1], h[g[i][k-1]][k-1]);
                
}
int main(void){
    make();
    prim();    
    solve();
//    printf("%lld\n", ans);
}

loj10137. 「一本通 4.4 练习 4」跳跳棋

loj2195. 「SDOI2014」旅行

#include<cstdio>
#include<iostream>
#include<queue>
#include<algorithm>
using namespace std;
const int maxn = 100010;
inline void qread(int &x){
    x = 0;
    register int ch = getchar();
    while(ch < '0' || ch > '9')    ch = getchar();
    while(ch >= '0' && ch <= '9')    x = 10 * x + ch - 48, ch = getchar();
}
int n, q;
struct list{
    int head[maxn];
    int go[maxn << 1];
    int nxt[maxn << 1];
}G;
int C[maxn];
int val[maxn];
int size[maxn];
int son[maxn];
int deep[maxn];
int f[maxn];
int top[maxn];
int seg[maxn];
int rev[maxn];
int end[maxn];
int pre[maxn];
inline void init(){
    qread(n);
    qread(q);
    for(int i=1; i<=n; ++i){
        int x;
        qread(val[i]);
        qread(x);
        C[i] = x;
    }
    for(int i=1; i<n; ++i){
        int x, y;
        qread(x), qread(y);
        G.go[i] = y;
        G.nxt[i] = G.head[x];
        G.head[x] = i;
        G.go[i + n] = x;
        G.nxt[i + n] = G.head[y];
        G.head[y] = i + n;
    }
    deep[1] = top[1] = seg[0] = seg[1] = rev[1] = 1;
}
void dfs1(int x){
    size[x] = 1;
    for(register int i = G.head[x]; i; i = G.nxt[i])
        if(!deep[G.go[i]]){
            f[G.go[i]] = x;
            deep[G.go[i]] = deep[x] + 1;
            dfs1(G.go[i]);
            size[x] += size[G.go[i]];
            if(size[G.go[i]] > size[son[x]])
                son[x] = G.go[i];
        }
}
void dfs2(int x){
    end[x] = x;
    if(son[x]){
        top[son[x]] = top[x];
        seg[son[x]] = ++seg[0];
        rev[seg[0]] = son[x];
        dfs2(son[x]);
        end[x] = end[son[x]];
    }
    for(register int i = G.head[x]; i; i = G.nxt[i])
        if(!top[G.go[i]]){
            top[G.go[i]] = G.go[i];
            seg[G.go[i]] = ++seg[0];
            rev[seg[0]] = G.go[i];
            dfs2(G.go[i]);
            end[x] = end[G.go[i]];
        }
}
vector <int> sum[maxn];

void treeask(int x, int y, int z){
    int fx = top[x], fy = top[y];
    while(fx != fy){
        if(deep[fx] < deep[fy])    swap(x, y), swap(fx, fy);
        ask(seg[fx], seg[x], z, 1);
        x = f[fx];
        fx = top[x];
    }
    if(deep[x] > deep[y])    swap(x, y);
    ask(seg[x], seg[y], z, 1);
}
int main(void)
{
    init();
    dfs1(1);
    dfs2(1);
    for(int i=1; i<=maxn-10; ++i)
        if(!C[i].empty())
            sort(C[i].begin(), C[i].end(), cmp);
    while(q--){
        string op;
        int x, y;
        cin >> op;
        qread(x);
        qread(y);
        SUM = 0;
        MAX = 0x80000000;
        if(op == "CC"){
            change(x, y);
            rC[x] = y;
        }
        else if(op == "CW"){
            val[x] = y;
        }
        else if(op == "QS"){
            treeask(x, y, rC[x]);
            printf("%d\n", SUM);
        }
        else{
            treeask(x, y, rC[x]);
            printf("%d\n", MAX);
        }
    }
}

loj10161. 「一本通 5.2 练习 4」叶子的颜色

 

loj10162. 「一本通 5.2 练习 5」骑士

loj10168. 「一本通 5.3 练习 3」恨 7 不成妻

 

posted @ 2018-08-14 18:56  junk_yao  阅读(192)  评论(0编辑  收藏  举报