2018年7月18日暑假训练日记

  一道网络流的题目:1006 Tricks Device,题意求隔断多少边可以去除最短路,其实就是裸的最小割,这里把流量限定为边的个数,跑一边网络流就可以了,比较思维的是dij算法的改造,改造求他最短路的长度。

 #include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
#include<cmath>
#include<vector>
#define maxn 2010
#define INF 1e9
using namespace std;
struct edge{
    edge(){};
    edge(int from,int to,int val,int flow):from(from),to(to),val(val),flow(flow){}
    int from,to,val,flow;
};
int n,m,f,d;
vector<edge>p;
vector<int>num[maxn];
bool visit[maxn];
bool vis[maxn];
int dis[maxn];
int cur[maxn];
int a[maxn][maxn];
int cnt[maxn][maxn];
int dist[maxn];
int number[maxn];
void add(int x,int y,int z){
    p.push_back(edge(x,y,z,0));
    p.push_back(edge(y,x,0,0));
    int xx=p.size();
    num[x].push_back(xx-2);
    num[y].push_back(xx-1);
}
bool bfs(int s,int t){
    int i,j;
    memset (visit,0,sizeof(visit));
    queue<int>qq;
    qq.push(s);
    dis[s]=0;
    visit[s]=1;
    while (!qq.empty()){
        int u=qq.front();
        qq.pop();
        for (i=0;i<num[u].size();i++){
            edge& e=p[num[u][i]];
            if (!visit[e.to]&&e.val>e.flow){
                visit[e.to]=1;
                dis[e.to]=dis[u]+1;
                qq.push(e.to);
            }
        }
    }
    return visit[t];
}
int dfs(int x,int t,int val){
    if (x==t||val==0){
        return val;
    }
    int flow=0,f;
    for (int& i=cur[x];i<num[x].size();i++){
        edge& e=p[num[x][i]];
        if (dis[x]+1==dis[e.to]&&(f=dfs(e.to,t,min(val,e.val-e.flow)))>0){
            e.flow+=f;
            p[num[x][i]^1].flow-=f;
            flow+=f;
            val-=f;
            if (val==0)break;
        }
    }
    return flow;
}
int dinic(int s,int t){
    int flow=0;
    while (bfs(s,t)){
        memset (cur,0,sizeof(cur));
        flow+=dfs(s,t,INF);
    }
    return flow;
}
int dij(){
    int i,j;
    memset (dist,0x3f,sizeof(dist));
    memset (number,0x3f,sizeof(number));
    memset(vis,0,sizeof(vis));
    number[1]=dist[1]=0;
    for (i=1;i<=n;i++){
        int mark=-1;
        int minn=INF;
        for (j=1;j<=n;j++){
            if (!vis[j]&&dist[j]<minn){
                minn=dist[j];
                mark=j;
            }
        }
        if (mark==-1) break;
        vis[mark]=1;
        for (j=1;j<=n;j++) if (!vis[j]&&a[mark][j]){
            if (dist[j]>minn+a[mark][j]){
                dist[j]=minn+a[mark][j];
                number[j]=number[mark]+1;
            }
            else if (dist[j]==minn+a[mark][j])number[j]=min(number[j],number[mark]+1);
        }
    }
    return number[n];
}
int main(){
    int i,j,k,l,x,y,z,t;
    while (scanf("%d%d",&n,&m)!=EOF){
        memset (a,0x3f,sizeof(a));
        memset (cnt,0,sizeof(cnt));
        for (i=1;i<=m;i++){
            scanf("%d%d%d",&x,&y,&z);
            if (z<a[x][y]){
                a[x][y]=a[y][x]=z;
                cnt[x][y]=cnt[y][x]=1;
            }
            else if (z==a[x][y]){
                cnt[x][y]++;
                cnt[y][x]++;
            }
        }
        int ans2=m-dij();
        p.clear();
        for (i=1;i<=n;i++){
            num[i].clear();
        }
        for (i=1;i<=n;i++){
            for (j=1;j<=n;j++){
                if (dist[i]==dist[j]+a[j][i]){
                    add(j,i,cnt[j][i]);
                }
            }
        }
        printf("%d %d\n",dinic(1,n),ans2);
    }
}

  然后一道规律题1020 I Wanna Become A 24-Point Master,在打表的过程中,当发现可以用x-x凑0的时候这个题目就变成了凑4和6的简单过程,前13项需要打表,到9还好,后面就费劲了,花了些时间。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
int main() {
    long long n,i,j;
    while (scanf("%lld",&n)!=EOF) {
        if (n==1||n==2||n==3)puts("-1");
        else if (n==4){
            printf("1 * 2\n");
            printf("5 + 3\n");
            printf("6 + 4\n");
        }
        else if (n==5){
            printf("1 * 2\n");
            printf("3 * 6\n");
            printf("7 - 4\n");
            printf("8 / 5\n");
        }
        else if (n==6){
            printf("1 + 2\n");
            printf("3 + 4\n");
            printf("5 / 6\n");
            printf("7 + 8\n");
            printf("9 * 10\n");
        }
        else if (n==7){
            printf("1 + 2\n");
            printf("3 + 4\n");
            printf("5 + 8\n");
            printf("6 + 9\n");
            printf("10 / 7\n");
            printf("11 + 12\n");
        }
        else if (n==8){
            printf("1 - 2\n");
            printf("3 - 4\n");
            printf("5 + 6\n");
            printf("7 * 9\n");
            printf("8 + 11\n");
            printf("10 + 13\n");
            printf("12 + 14\n");
        }
        else if (n==9){
            printf("1 + 2\n");
            printf("3 + 4\n");
            printf("5 - 6\n");
            printf("7 + 10\n");
            printf("8 + 11\n");
            printf("13 / 9\n");
            printf("14 - 15\n");
            printf("16 + 12\n");
        }
        else if (n==10){
            printf("1 + 2\n");
            printf("3 / 4\n");
            printf("5 / 6\n");
            printf("7 / 8\n");
            printf("9 / 10\n");
            printf("11 + 12\n");
            printf("13 + 16\n");
            printf("14 + 17\n");
            printf("15 + 18\n");
        }
        else if (n==11){
            printf("1 + 2\n");
            printf("3 - 4\n");
            printf("5 - 6\n");
            printf("7 / 8\n");
            printf("9 / 10\n");
            printf("12 + 15\n");
            printf("11 * 13\n");
            printf("14 * 18\n");
            printf("16 + 17\n");
            printf("19 + 20\n");
        }
        else if (n==12){
            printf("1 + 2\n");
            printf("13 + 3\n");
            printf("14 + 4\n");
            printf("15 / 5\n");
            printf("6 + 7\n");
            printf("17 + 8\n");
            printf("18 + 9\n");
            printf("19 + 10\n");
            printf("20 + 11\n");
            printf("21 / 12\n");
            printf("16 * 22\n");
        }
        else if (n==13){
            printf("1 + 2\n");
            printf("14 / 3\n");
            printf("4 + 5\n");
            printf("16 / 6\n");
            printf("7 + 8\n");
            printf("18 / 9\n");
            printf("10 + 11\n");
            printf("20 + 12\n");
            printf("21 / 13\n");
            printf("15 * 17\n");
            printf("23 * 19\n");
            printf("24 * 22\n");
        }
        else {
            printf("1 + 2\n");
            printf("%lld + 3\n",n+1);
            printf("%lld + 4\n",n+2);
            printf("%lld / 5\n",n+3);
            printf("6 + 7\n");
            printf("%lld + 8\n",n+5);
            printf("%lld + 9\n",n+6);
            printf("%lld + 10\n",n+7);
            printf("%lld + 11\n",n+8);
            printf("%lld / 12\n",n+9);
            printf("%lld * %lld\n",n+4,n+10);
            printf("14 - 13\n");
            if (n>=15){
                for (i=15;i<=n;i++){
                    printf("%lld * %lld\n",n+i-3,i);
                }
            }
            printf("%lld + %lld\n",n+11,2*n-2);
        }

    }
}
 

猜你喜欢

转载自blog.csdn.net/m0_37772713/article/details/81104357