DQS DQS

HIT Summer Training Day6 最短路|最小生成树|欧拉路

in 最短路,最小生成树,算法,图论,欧拉路,模拟赛read (207) 文章转载请注明来源!

以后要注意PE…………


A : codeforces - 500A

遍历图,当时复制了一个最短路过了233

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<queue>
using namespace std;

typedef long long LL;
const int SZ = 100010;
const int INF = 1e9+7;

int head[SZ],nxt[SZ],tot = 1,n,m,s,e;

struct edge
{
    int t,d;
}l[SZ];

void build(int f,int t,int d)
{
    l[++ tot] = (edge){t,d};
    nxt[tot] = head[f];
    head[f] = tot;
}

queue<int> q;
int dist[SZ];
bool use[SZ];

int spfa(int s,int e)
{
    while(q.size()) q.pop();
    memset(use,0,sizeof(use));
    memset(dist,63,sizeof(dist));
    dist[s] = 0;
    use[s] = 1;
    q.push(s);
    while(q.size())
    {
        int u = q.front(); q.pop();
        use[u] = 0;
        for(int i = head[u];i;i = nxt[i])
        {
            int v = l[i].t;
            if(dist[v] > dist[u] + l[i].d)
            {
                dist[v] = dist[u] + l[i].d;
                if(!use[v])
                    use[v] = 1,q.push(v);
            }
        }
    }
    return dist[e];
}

int main()
{
    while(~scanf("%d%d",&n,&e))
    {
        memset(head,0,sizeof(head)); tot = 1;
        for(int i = 1;i <= n - 1;i ++)
        {
            int a,b,c;
            scanf("%d",&a);
            build(i,i + a,1);
        }
        s = 1;
        if(spfa(s,e) > INF) puts("NO");
        else puts("YES");
    }
    return 0;
}


B : hoj - 3204

给你一颗树,问你最多画几笔可以覆盖所有边。每条边只能走一遍。

其实对于树上,每条路径都删除一对奇度点。答案是奇度点数量除以二,并且奇度点一定有偶数个。

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<queue>
using namespace std;

typedef long long LL;
const int SZ = 100010;
const int INF = 1e9+7;

int du[SZ],n,m,s,e;


int main()
{
    int T;
    scanf("%d",&T);
    while(T --)
    {
        memset(du,0,sizeof(du));
        scanf("%d",&n);
        for(int i = 1;i <= n - 1;i ++)
        {
            int a,b,c;
            scanf("%d%d",&a,&b);
            du[a] ++; du[b] ++;
        }
        int ans = 0;
        for(int i = 1;i <= n;i ++)
            if(du[i] & 1) ans ++;
        printf("%d\n",ans >> 1);
    }
    return 0;
}


C : codeforces - 508D

给n个长度为3的字符串,一个字符串的前两个字符和另一个的后两个字符相同那么它们能连起来。问能否连成一个长度为n+2的字符串,能则输出解。

建边后就是找一个欧拉路,可dfs。
注意要回溯的时候加入答案,因为如果之前加入,后面可能不对。

这个题有可能导致一个点多次访问(它向每个点伸出一条边,每个点也向他伸一条边),如果每次都访问所有边,会TLE。
所以要加一个类似当前弧优化的东西

#include<iostream>
#include<cstring>
#include<algorithm>
#include<cstdio>
#include<queue>
#include<map>
using namespace std;

typedef long long LL;
const int SZ = 1000010;
const int INF = 1000000010;

map<string,int> mp;
string f[SZ];

int head[SZ],nxt[SZ],tot = 1,to[SZ],n;

void build(int f,int t)
{
    to[++ tot] = t;
    nxt[tot] = head[f];
    head[f] = tot;
}

int len = 0;
char ans[SZ];

bool use[SZ];

void dfs(int u)
{
    for(int &i = head[u];i;i = nxt[i])
    {
        int v = to[i];
        if(!use[i])
            use[i] = 1,dfs(v);
    }
    ans[++ len] = f[u][1];
}

int du[SZ];

bool check()
{
    int t = 0;
    for(int i = 1;i <= n;i ++)
        if(du[i])
        {
            if(du[i] != -1 && du[i] != 1)
                return false;
        }
        else t ++;
    if(t != n && t != n - 2)
        return false;
    return true;
}

int main()
{
    int N;
    scanf("%d",&N); getchar();
    for(int i = 1;i <= N;i ++)
    {
        char s[5];
        scanf("%s",s);
        string a,b;
        a += s[0]; a += s[1];
        b += s[1]; b += s[2];
        if(!mp[a]) { mp[a] = ++ n,f[n] = a; }
        if(!mp[b]) { mp[b] = ++ n,f[n] = b; }
        int x = mp[a],y = mp[b];
        build(x,y);
        du[x] ++; du[y] --;
    }
    if(!check()) { puts("NO"); return 0; }
    int s = 1;
    for(int i = 1;i <= n;i ++)
        if(du[i] == 1) s = i;
    dfs(s);
    ans[++ len] = f[s][0];
    if(len != N + 2) { puts("NO"); return 0; }
    puts("YES");
    for(int i = len;i >= 1;i --)
        printf("%c",ans[i]);
    return 0;
}


D : poj - 3660

给一些形如"A能打败B"的关系,并且这个关系具有传递性。问最多能确定多少人的rank。

建图,用floyd求出每个点能打败多少点。然后进行k次枚举,每次计算当前点集中能打败u的人数和u能打败·的人数,来看看u能否确定rank。能确定就从当前点集删除,继续。

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<queue>
using namespace std;

typedef long long LL;
const int SZ = 1010;
const int INF = 1e9+7;

int n,m;

int f[SZ][SZ],fa[SZ];

int find(int x) { return x == fa[x] ? x : fa[x] = find(fa[x]); }

void Union(int a,int b)
{
    int x = find(a),y = find(b);
    if(x != y) fa[x] = y;
}

bool use[SZ];

int main()
{
    scanf("%d%d",&n,&m);
    for(int i = 1;i <= n;i ++) fa[i] = i;

    for(int i = 1;i <= m;i ++)
    {
        int a,b,c;
        scanf("%d%d",&a,&b);
        f[a][b] = 1; Union(a,b);
    }
    int t = 0;
    for(int i = 1;i <= n;i ++)
        if(find(i) == i) t ++;
    if(t != 1) { puts("0"); return 0; }

    for(int k = 1;k <= n;k ++)
        for(int i = 1;i <= n;i ++)
            for(int j = 1;j <= n;j ++)
                f[i][j] |= (f[i][k] & f[k][j]);
/*    for(int i = 1;i <= n;i ++,puts(""))
        for(int j = 1;j <= n;j ++)
            cout << f[i][j] << " ";*/
    int now = n;
    for(int k = 1;k <= n;k ++)
    {
        for(int i = 1;i <= n;i ++)
        {
            if(use[i]) continue;
            int num1 = 0,num2 = 0;
            for(int j = 1;j <= n;j ++)
            {
                if(use[j]) continue;
                if(f[i][j]) num1 ++;
                if(f[j][i]) num2 ++;
            }
            if(num1 == now - 1 || num2 == now - 1 || num1 + num2 + 1 == now)
                use[i] = 1,now --;
        }
    }
    printf("%d\n",n - now);
    return 0;
}


E : poj - 3522

求一个生成树使最大边-最小边差值最小。

枚举最小边做最小生成树。

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<queue>
using namespace std;

typedef long long LL;
const int SZ = 1000010;
const int INF = 1e9+7;

int head[SZ],nxt[SZ],tot = 1,n,m;


struct edge2
{
    int f,t,d;
}ll[SZ];

bool cmp(edge2 a,edge2 b)
{
    return a.d < b.d;
}

int fa[SZ];

int find(int x) { return x == fa[x] ? x : fa[x] = find(fa[x]); }

int main()
{
    while(~scanf("%d%d",&n,&m) && n)
    {
        for(int i = 1;i <= m;i ++)
            scanf("%d%d%d",&ll[i].f,&ll[i].t,&ll[i].d);
        sort(ll + 1,ll + 1 + m,cmp);
        int ans = INF;
        for(int i = 1;i <= m;i ++)
        {
            for(int j = 1;j <= n;j ++) fa[j] = j;

            int minn = ll[i].d,maxn = -INF;
            for(int j = i;j <= m;j ++)
            {
                int a = ll[j].f,b = ll[j].t;
                int x = find(a),y = find(b);
                if(x != y) { maxn = max(maxn,ll[j].d); fa[x] = y; }
            }
            int t = 0;
            for(int j = 1;j <= n;j ++)
                if(find(j) == j) t ++;
            if(t > 1) continue;
            if(maxn != -INF)
                ans = min(ans,maxn - minn);
        }
        printf("%d\n",ans < INF ? ans : -1);
    }
    return 0;
}


F : hdu - 1301

裸的最小生成树

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<queue>
using namespace std;

typedef long long LL;
const int SZ = 1000010;
const int INF = 1e9+7;

int head[SZ],nxt[SZ],tot = 1,n,m;


struct edge2
{
    int f,t,d;
}ll[SZ];

bool cmp(edge2 a,edge2 b)
{
    return a.d < b.d;
}

int fa[SZ];

int find(int x) { return x == fa[x] ? x : fa[x] = find(fa[x]); }

int main()
{
    while(~scanf("%d",&n) && n)
    {
        memset(head,0,sizeof(head)); tot = 1;
        for(int i = 1;i <= n;i ++) fa[i] = i;
        int tot = 0;
        for(int i = 1;i <= n - 1;i ++)
        {
            char s[2]; int d,k;
            scanf("%s%d",s,&k);
            int u = s[0] - 'A' + 1;
            while(k --)
            {
                scanf("%s%d",s,&d);
                int v = s[0] - 'A' + 1;
                ll[++ tot] = (edge2){u,v,d};
            }
        }
        sort(ll + 1,ll + 1 + tot,cmp);
        int ans = 0;
        for(int i = 1;i <= tot;i ++)
        {
            int a = ll[i].f,b = ll[i].t;
            int x = find(a),y = find(b);
            if(x != y) ans += ll[i].d,fa[x] = y;
        }
        printf("%d\n",ans);
    }
    return 0;
}


G : hdu - 2066

多个起点和终点的最短路。

建虚点,水题

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<queue>
using namespace std;

typedef long long LL;
const int SZ = 100010;
const int INF = 1e9+7;

int head[SZ],nxt[SZ],tot = 1,n = 1000,m;

struct edge
{
    int t,d;
}l[SZ];

void build(int f,int t,int d)
{
    l[++ tot] = (edge){t,d};
    nxt[tot] = head[f];
    head[f] = tot;
}

queue<int> q;
int dist[SZ];
bool use[SZ];

int spfa(int s,int e)
{
    while(q.size()) q.pop();
    memset(use,0,sizeof(use));
    memset(dist,63,sizeof(dist));
    dist[s] = 0;
    use[s] = 1;
    q.push(s);
    while(q.size())
    {
        int u = q.front(); q.pop();
        use[u] = 0;
        for(int i = head[u];i;i = nxt[i])
        {
            int v = l[i].t;
            if(dist[v] > dist[u] + l[i].d)
            {
                dist[v] = dist[u] + l[i].d;
                if(!use[v])
                    use[v] = 1,q.push(v);
            }
        }
    }
    return dist[e];
}

int main()
{
    int n,S,D;
    while(~scanf("%d%d%d",&m,&S,&D))
    {
        memset(head,0,sizeof(head)); tot = 1;
        for(int i = 1;i <= m;i ++)
        {
            int a,b,c;
            scanf("%d%d%d",&a,&b,&c);
            build(a,b,c); build(b,a,c);
        }
        int s = 1001,e = 1002;
        for(int i = 1;i <= S;i ++)
        {
            int a;
            scanf("%d",&a);
            build(s,a,0);
        }
        for(int i = 1;i <= D;i ++)
        {
            int a;
            scanf("%d",&a);
            build(a,e,0);
        }
        printf("%d\n",spfa(s,e));
    }
    return 0;
}


H : hdu - 5637

有以下两种操作:

1.将数x的某个二进制取反。

2.将x与给定的数表中某个数异或。

给最多15个数,给10w组询问,每次询问"x,y"为x变成y最多需要几步。

考虑x变成y:如果某一个二进制位不相同,那么就需要让这一位变化,记为1。如果这个二进制位相同,那么这一位就不需要变化,记为0。我们发现现在问题变成让得到的这个数变为0所需的最小操作数,即为0变成这个数所需的最小操作数。

我们发现按照上述表述,这个值是x^y。

这样就成了从0开始的单源最短路。

注意,因为异或所以可能得到的点的大小有14w

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<queue>
using namespace std;

typedef long long LL;
const int SZ = 1000010;
const int INF = 1e9;
const int mod = 1000000007;


int n,m,a[SZ];


queue<int> q;
int dist[SZ];
bool use[SZ];

void spfa(int s)
{
    memset(dist,63,sizeof(dist));
    dist[s] = 0;
    use[s] = 1;
    q.push(s);
    while(q.size())
    {
        int u = q.front(); q.pop();
        use[u] = 0;
        for(int i = 1;i <= n;i ++)
        {
            int v = u ^ a[i];
            if(v > 1000000) continue;
            if(dist[v] > dist[u] + 1)
            {
                dist[v] = dist[u] + 1;
                if(!use[v]) use[v] = 1,q.push(v);
            }
        }
        for(int i = 0;i <= 18;i ++)
        {
            int v = u ^ (1 << i);
            if(v > 1000000) continue;
            if(dist[v] > dist[u] + 1)
            {
                dist[v] = dist[u] + 1;
                if(!use[v]) use[v] = 1,q.push(v);
            }
        }
    }
    //for(int i = 1;i <= n;i ++) printf("%d ",a[i]); puts("");
    //for(int i = 0;i <= 100000;i ++) printf("%d ",dist[i]); puts("");
}


int main()
{
//    cout << (1 << 18) << endl;
    int T;
    scanf("%d",&T);
    while(T --)
    {
        scanf("%d%d",&n,&m);
        for(int i = 1;i <= n;i ++) scanf("%d",&a[i]);
        spfa(0);
        int ans = 0;
        for(int i = 1;i <= m;i ++)
        {
            int x,y;
            scanf("%d%d",&x,&y);
            ans = (ans + (LL)i * dist[x ^ y] % mod) % mod;
        }
        printf("%d\n",ans);
    }
    return 0;
}



I : codeforces - 449B

给一些公路,和一些只会从1号点出去的火车道。问最多去掉多少火车道使得1号点到每个点的最短路不变。

最短路径树。要注意我们要尽量保留公路的边而不是火车的边,并且要保证是最短路。松弛改一下就行。

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<queue>
using namespace std;

typedef long long LL;
const int SZ = 4000010;
const int INF = 1e9+7;

int head[SZ],nxt[SZ],tot = 1,n,m,k;
int pre[SZ];

struct edge
{
    int t;
    LL d;
    int id;
    edge() {}
    edge(int a,LL b,int c) { t = a,d = b,id = c; }
}l[SZ];

void build(int f,int t,LL d,int id)
{
    l[++ tot] = edge(t,d,id);
    nxt[tot] = head[f];
    head[f] = tot;
}

deque<int> q;
LL dist[SZ];
bool use[SZ];


void spfa(int s)
{
    dist[s] = 0;
    q.push_front(s);
    use[s] = 1;
    while(q.size())
    {
        int u = q.front(); q.pop_front();
        use[u] = 0;
        for(int i = head[u];i;i = nxt[i])
        {
            int v = l[i].t;
            if(dist[v] > dist[u] + l[i].d || (dist[v] == dist[u] + l[i].d && l[pre[v]].id > m && l[i].id <= m))
            {
                dist[v] = dist[u] + l[i].d;
                pre[v] = i;
                if(!use[v])
                {
                    use[v] = 1;
                    if(q.empty()) q.push_front(v);
                    else
                    {
                        if(dist[v] > dist[q.front()]) q.push_back(v);
                        else q.push_front(v);
                    }
                }
            }
        }
    }
}

bool vis[SZ];

int main()
{
    scanf("%d%d%d",&n,&m,&k);
    memset(dist,63,sizeof(dist));
    memset(head,0,sizeof(head)); tot = 1;
    for(int i = 1;i <= m;i ++)
    {
        int a,b;
        LL c;
        scanf("%d%d%I64d",&a,&b,&c);
        build(a,b,c,i); build(b,a,c,i);
    }
    for(int i = 1;i <= k;i ++)
    {
        int b; LL c;
        scanf("%d%I64d",&b,&c);
        build(1,b,c,i + m);  build(b,1,c,i + m);
    }
    spfa(1);
    int ans = k;
    //for(int u = 2;u <= n;u ++)
    //    printf("%d ",l[pre[u]].id); puts("");
    for(int u = 2;u <= n;u ++)
    {
        int x = l[pre[u]].id;
        if(x > m && !vis[x]) ans --,vis[x] = 1;
    }
    printf("%d\n",ans);
    return 0;
}


J : codeforces - 545E

求一个最短路径树并且使树上权值和最小。

松弛那边改一下就完了,这么水竟然是E……

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<queue>
using namespace std;

typedef long long LL;
const int SZ = 2000010;
const int INF = 1e9+7;

int head[SZ],nxt[SZ],tot = 1,n,m,k,s;
int pre[SZ];

struct edge
{
    int t;
    LL d;
    int id;
    edge() {}
    edge(int a,LL b,int c) { t = a,d = b,id = c; }
}l[SZ];

void build(int f,int t,LL d,int id)
{
    l[++ tot] = edge(t,d,id);
    nxt[tot] = head[f];
    head[f] = tot;
}

queue<int> q;
LL dist[SZ];
bool use[SZ];

void spfa(int s)
{
    memset(dist,63,sizeof(dist));
    dist[s] = 0;
    q.push(s);
    use[s] = 1;
    while(q.size())
    {
        int u = q.front(); q.pop();
        use[u] = 0;
        for(int i = head[u];i;i = nxt[i])
        {
            int v = l[i].t;
            if(dist[v] > dist[u] + l[i].d || (dist[v] == dist[u] + l[i].d && l[pre[v]].d > l[i].d))
            {
                dist[v] = dist[u] + l[i].d;
                pre[v] = i;
                if(!use[v])
                    use[v] = 1,q.push(v);
            }
        }
    }
}

bool vis[SZ];

int main()
{
    scanf("%d%d",&n,&m);

    for(int i = 1;i <= m;i ++)
    {
        int a,b; LL c;
        scanf("%d%d%I64d",&a,&b,&c);
        build(a,b,c,i); build(b,a,c,i);
    }
    scanf("%d",&s);
    spfa(s);
    LL ans = 0;
    for(int u = 1;u <= n;u ++)
        if(u != s)
            ans += l[pre[u]].d;
    printf("%I64d\n",ans);

    for(int u = 1;u <= n;u ++)
        if(u != s)
            printf("%d ",l[pre[u]].id);
    return 0;
}


K : hdu - 5521

给n个点,m个集合。每个集合中有许多点,这些点两两之间有权值为ti的边。两个人一个从1一个从n一起走,只能从点上相遇,问相遇的最小时间以及可能相遇的点。

每个集合建一个虚点,每个点向它建长为ti的边,它再向每个点建长度为0的边。然后从1和n分别跑最短路就行了……

辣鸡题PE返回WA,改到我怀疑人生。

#include<iostream>
#include<cstring>
#include<algorithm>
#include<cstdio>
#include<queue>
using namespace std;

typedef long long LL;
const int SZ = 10000010;
const LL INF = 4e18;

LL read()
{
    char a = getchar();
    LL n = 0; bool flag = 0;
    while(a > '9' || a < '0') { if(a == '-') flag = 1; a = getchar(); }
    while('0' <= a && a <= '9' ) { n = n * 10 + a - '0'; a = getchar(); }
    if(flag) n = -n;
    return n;
}

int head[SZ],nxt[SZ],tot = 1,n,m;

struct edge
{
    int t; LL d;
}l[SZ];

void build(int f,int t,LL d)
{
    l[++ tot] = (edge){t,d};
    nxt[tot] = head[f];
    head[f] = tot;
}


queue<int> q;
LL dist1[SZ],dist2[SZ];
bool use[SZ];

void spfa1(int s)
{
    memset(dist1,63,sizeof(dist1));
    dist1[s] = 0;
    use[s] = 1;
    q.push(s);
    while(q.size())
    {
        int u = q.front(); q.pop();
        use[u] = 0;
        for(int i = head[u];i;i = nxt[i])
        {
            int v = l[i].t;
            if(dist1[v] > dist1[u] + l[i].d)
            {
                dist1[v] = dist1[u] + l[i].d;
                if(!use[v])
                    use[v] = 1,q.push(v);
            }
        }
    }
}


void spfa2(int s)
{
    memset(dist2,63,sizeof(dist2));
    dist2[s] = 0;
    use[s] = 1;
    q.push(s);
    while(q.size())
    {
        int u = q.front(); q.pop();
        use[u] = 0;
        for(int i = head[u];i;i = nxt[i])
        {
            int v = l[i].t;
            if(dist2[v] > dist2[u] + l[i].d)
            {
                dist2[v] = dist2[u] + l[i].d;
                if(!use[v])
                    use[v] = 1,q.push(v);
            }
        }
    }
}

int main()
{
    int T;
    scanf("%d",&T);
    for(int cc = 1;cc <= T;cc ++)
    {
        scanf("%d%d",&n,&m);
        memset(head,0,sizeof(head)); tot = 1;
        for(int i = 1;i <= m;i ++)
        {
            LL t = read(); int k = read();
            while(k --)
            {
                int x = read();
                build(x,i + n,t); build(i + n,x,0);
            }
        }
        if(n <= 0) {printf("Case #%d: Evil John\n",cc); continue;}
        spfa1(1); spfa2(n);
        LL ans = INF;
    //    cout << ans << endl;
    //    for(int i = 1;i <= n;i ++) printf("%d ",dist1[i]); puts("");
    //    for(int i = 1;i <= n;i ++) printf("%d ",dist2[i]); puts("");
        for(int i = 1;i <= n;i ++)
            ans = min(ans,max(dist1[i],dist2[i]));
        printf("Case #%d: ",cc);
        if(ans >= INF) puts("Evil John");
        else
        {
            int t = 0;
            for(int i = 1;i <= n;i ++)
                if(ans == max(dist1[i],dist2[i]))
                    t ++;
            printf("%lld\n",ans);
            for(int i = 1,j = 0;i <= n;i ++)
                if(ans == max(dist1[i],dist2[i]))
                    printf("%d%c",i,++ j == t ? '\n' : ' ');
        }
    }
    return 0;
}



L : hoj - 3097

有n个点m条边,其中k个点是important的,问最少删除多少边使得这k个点不形成环。

可以发现最少删除的边数是总边数-树边,对于不是important的点,可以缩起来看做一个点。然后做一遍生成树就行了。

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<queue>
using namespace std;

typedef long long LL;
const int SZ = 1000010;
const int INF = 1e9+7;

int n,m;


struct edge2
{
    int f,t,d;
}ll[SZ];

bool cmp(edge2 a,edge2 b)
{
    return a.d < b.d;
}

int fa[SZ];

int find(int x) { return x == fa[x] ? x : fa[x] = find(fa[x]); }

void Union(int a,int b)
{
    int x = find(a),y = find(b);
    if(x != y) fa[x] = y;
}

int main()
{
    int T;
    scanf("%d",&T);
    for(int cc = 1;cc <= T;cc ++)
    {
        int k;
        scanf("%d%d%d",&n,&m,&k);
        for(int i = 1;i <= n;i ++) fa[i] = i;
        int ans = m;
        for(int i = 1;i <= m;i ++)
        {
            scanf("%d%d",&ll[i].f,&ll[i].t);
            ll[i].f ++,ll[i].t ++;
            if(ll[i].f > k && ll[i].t > k)
                Union(ll[i].f,ll[i].t),ans --;
        }
        int ans1 = ans,t = 0;// cout << ans << endl;
        for(int i = 1;i <= m;i ++)
        {
            int a = ll[i].f,b = ll[i].t;
            int x = find(a),y = find(b);
            if(x != y) fa[x] = y,t ++;
        }
        printf("Case #%d: %d\n",cc,ans1 - t);
    }
    return 0;
}
/*
233
8 10 3
0 6
3 4
1 6
0 5
2 7
1 6
3 4
2 5
1 6
0 1


*/

jrotty WeChat Pay

微信打赏

jrotty Alipay

支付宝打赏

文章二维码

扫描二维码,在手机上阅读!

发表新评论
博客已萌萌哒运行
© 2018 由 Typecho 强力驱动.Theme by Yodu
前篇 后篇
雷姆
拉姆