Codeforces Round #625 (Div. 2,)

A
对于两个人都有的全看为1即可,不必统计。第二个人可以解决而第一个人不能解决的统计为1,然后在统计第二个人不能解决而第一个人可以解决的,然后在讨论下即可。
B
c c c为位置, b c b_c bc c c c位置的值。然后 c i + 1 − c i = b c i + 1 − b c i c_{i+1}-c_i=b_{c_{i+1}}-b_{c_i} ci+1ci=bci+1bci
其实可以写为 b r − r = b l − l b_r-r=b_l-l brr=bll
然后我们只需要统计 b i − i b_i-i bii相等的和的最大值。
C
这个题目我似乎理解错题意了。。。。原题中说,相邻字符是它的前驱那么这个字符可以删除。。。。
不过贪心的做法这两个意思都能过,如果能删除,优先考虑删除较大字符,这样比后续并没有影响,因为可能会有小的字符可以发挥作用删除多个比它大的字符。
D
极度不友好,英语杀我,阅读理解?
题意:给你一条路径,从 p 1 p_1 p1 p n p_n pn,然后让你沿着这个路开车,车上有导航,这个导航只导最短的路径,问你这个导航会最多和最少重设多少次。
思路:
对于最少:如果一条边在< p i p_i pi, p i + 1 p_{i+1} pi+1>在最短的路径中,则不需要重设,否则累加1即可。
对于最多,< p i p_i pi, p i + 1 p_{i+1} pi+1>不在最短路径中毫无疑问,然后如果在,那么检查是否有其余的 p i p_i pi p n p_n pn的最短路,如果有,那么为了最多,可以累加1。
图论啊,本来学的不好,还都忘了。。。。还不努力。。。。难受!

struct Edge
{
     
    int next;
    int to;
    int dis;
}edge[N],redge[N];
struct node
{
     
    int id,val;
    node(){
     }
    node(int x,int y):id(x),val(y){
     }
    bool operator <(node A)const 
    {
     
        return val>A.val;
    }
};
int head[N],rhead[N],rtot,tot;
int d[N],vis[N];
inline void add(int from,int to,int dis)
{
     
    edge[++tot].next = head[from];
    edge[tot].to = to;
    edge[tot].dis = dis;
    head[from] = tot;
}
inline void radd(int from,int to){
     
    redge[++rtot].next = rhead[from];
    redge[rtot].to = to;
    rhead[from] = rtot;
}
inline void init()
{
     
    memset(head,-1,sizeof(head));
    memset(vis,0,sizeof(vis));
    memset(d,0x3f,sizeof(d));
    }
void Dijkstra(int u)
{
     
    priority_queue<node> Q;
    Q.push(node(u,0));
    d[u] = 0;
    node tmp;
    while(Q.size())
    {
     
        tmp = Q.top();
        Q.pop();
        int x = tmp.id;
        if(vis[x]) continue;
        vis[x] = 1;
        for(int i = head[x];~i;i = edge[i].next)
        {
     
            int y  = edge[i].to;
            int dis = edge[i].dis;
            if(d[y]>d[x] + dis)
            {
     
                d[y] = d[x] + dis;
                Q.push(node(y,d[y]));
            }
        }
    }
}
int p[N];
int main(){
     
    init();
    int n = read(),m = read();
    rep(i,1,m){
     
        int u = read(),v = read();
        add(v,u,1);
        radd(u,v);
    }
    int h = read();
    rep(i,1,h) p[i] = read();
    Dijkstra(p[h]);
    int ans1 = 0,ans2 = 0;
    rep(i,1,h-1){
     
        int u = p[i],v = p[i+1];
        if(d[u] != d[v]+1) ans1 ++,ans2 ++;
        else {
     
            for(int j = rhead[u];j;j = redge[j].next){
     
                int y = redge[j].to;
                if(d[u] == d[y]+1&&y!=v) {
     ans2++;break;}
            }
        }
    }
    cout << ans1 << ' '<<ans2<<endl;
}

E

你可能感兴趣的:(Contest)