zoukankan      html  css  js  c++  java
  • ZOJ Monthly, July 2015

     B http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=5552

    输入n,表示有n个数1到n。A先拿,B后拿,依次拿,每次可以拿任意一个数,同时会删去这个数的所有因子,最后谁没得拿了谁输。

    解法:推了前几个,0,a输,别的a都能赢,证明没想,猜过去的。

    网上一个人说的,也不是很清晰:“如果先取的在2-n中取必输,则先取1, 
    否则则在2-n中取,同时会把1取走,必赢”

    1 #include<cstdio>
    2 int main(){
    3     int n;
    4     while(~scanf("%d",&n)){
    5         puts(n?"win":"fail");
    6     }
    7     return 0;
    8 }
    View Code

    http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=5555

    n点m边无向图,每个点原来有ai,每个点最终需要bi,有边连就可以把任意个物品移动过去,移动一个物品的花费是1.

    解法:最小费用最大流,比赛时建图如下

    图中每个点拆成两个点u,u*,源点s连接每一个u,流量是ai,费用为0,ui 到 ui * 流量inf,费用为0, 输入的边在u之间建双向边,流量inf,费用1.

    每一个 ui* 连汇点t,流量bi,费用0.

    最后最大流要是sum of bi说明存在解,否则-1. 费用只会产生在u之间的边,最小费用就是这个题的答案。

      1 #include<cstdio>
      2 #include<cstring>
      3 #include<queue>
      4 #define mt(a,b) memset(a,b,sizeof(a))
      5 using namespace std;
      6 const int inf=0x3f3f3f3f;
      7 const int M=110;
      8 class MaxFlowMinCost { ///最小费用最大流 o(ME)
      9     typedef int typef;///流量的类型
     10     typedef int typec;///费用的类型
     11     static const int ME=2e6+10;///边的个数
     12     static const int MV=2e2+10;///点的个数
     13     queue<int> q;
     14     int cur[MV],pre[MV];
     15     bool used[MV],sign[MV];
     16     typef flow;
     17     typec cost,dist[MV];
     18     bool spfa(int s,int t) {
     19         mt(used,0);
     20         mt(sign,0);
     21         mt(dist,0);
     22         used[s]=sign[s]=true;
     23         while(!q.empty()) q.pop();
     24         q.push(s);
     25         while(!q.empty()) {
     26             int u=q.front();
     27             q.pop();
     28             used[u]=false;
     29             for(int i=g.head[u]; ~i; i=g.e[i].next) {
     30                 if(g.e[i].flow<1) continue;
     31                 int v=g.e[i].v;
     32                 typec c=g.e[i].cost;
     33                 if(!sign[v]||dist[v]>dist[u]+c) {
     34                     dist[v]=dist[u]+c;
     35                     sign[v]=true;
     36 
     37                     pre[v]=u;
     38                     cur[v]=i;
     39                     if(used[v]) continue;
     40                     used[v]=true;
     41                     q.push(v);
     42                 }
     43             }
     44         }
     45         return sign[t];
     46     } struct G {
     47         struct E {
     48             int v,next;
     49             typef flow;
     50             typec cost;
     51         } e[ME];
     52         int le,head[MV];
     53         void init() {
     54             le=0;
     55             mt(head,-1);
     56         } void add(int u,int v,typef flow,typec cost) {
     57             e[le].v=v;
     58             e[le].flow=flow;
     59             e[le].cost=cost;
     60             e[le].next=head[u];
     61             head[u]=le++;
     62         }
     63     } g;
     64 public:
     65     void init() {
     66         g.init();
     67     } void add(int u,int v,typef flow,typec cost) {
     68         g.add(u,v,flow,cost);
     69         g.add(v,u,0,-cost);
     70     } void solve(int s,int t) {
     71         flow=cost=0;
     72         while(spfa(s,t)) {
     73             int temp=t;
     74             typef now=inf;
     75             while(temp!=s) {
     76                 now=min(now,g.e[cur[temp]].flow);
     77 
     78                 temp=pre[temp];
     79             }
     80             flow+=now;
     81             temp=t;
     82             while(temp!=s) {
     83                 int id=cur[temp];
     84                 cost+=now*g.e[id].cost;
     85                 g.e[id].flow-=now;
     86                 g.e[id^1].flow+=now;
     87                 temp=pre[temp];
     88             }
     89         }
     90     } typef getflow() {
     91         return flow;
     92     } typec getcost() {
     93         return cost;
     94     }
     95 }mfmc;
     96 int a[M],b[M];
     97 int main() {
     98     int n,m,u,v;
     99     while(~scanf("%d%d",&n,&m)) {
    100         for(int i=1; i<=n; i++) {
    101             scanf("%d%d",&a[i],&b[i]);
    102         }
    103         mfmc.init();
    104         int s=n+n+1;
    105         int t=s+1;
    106         int sum=0;
    107         for(int i=1;i<=n;i++){
    108             mfmc.add(s,i,a[i],0);
    109             mfmc.add(i+n,t,b[i],0);
    110             mfmc.add(i,i+n,inf,0);
    111             sum+=b[i];
    112         }
    113         while(m--) {
    114             scanf("%d%d",&u,&v);
    115             mfmc.add(u,v,inf,1);
    116             mfmc.add(v,u,inf,1);
    117         }
    118         mfmc.solve(s,t);
    119         int ans=-1;
    120         if(sum==mfmc.getflow()){
    121             ans=mfmc.getcost();
    122         }
    123         printf("%d
    ",ans);
    124     }
    125     return 0;
    126 }
    View Code

     后来看网上有个建图更好,不用拆点,想想也是,中间流量inf,费用0,那些就直接流过去了,我们可以在脑子把他跑掉,也就是我们只需要对n个点建图,对于输入的边,还是在uv之间建流量inf费用1的双向边,对于a》b的情况,从源点到u连a-b的流,费用0,对于a《b的情况,从u连到汇点t,流量b-a,。a==b的不用连了,这样建图的贪心的默认自己留给自己是最好的,想想也是挺对的。源点出来的流相当于每个点可提供的,流向汇点的相当于每个点的需求。

      1 #include<cstdio>
      2 #include<cstring>
      3 #include<queue>
      4 #define mt(a,b) memset(a,b,sizeof(a))
      5 using namespace std;
      6 const int inf=0x3f3f3f3f;
      7 const int M=110;
      8 class MaxFlowMinCost { ///最小费用最大流 o(ME)
      9     typedef int typef;///流量的类型
     10     typedef int typec;///费用的类型
     11     static const int ME=6e2+10;///边的个数
     12     static const int MV=1e2+10;///点的个数
     13     queue<int> q;
     14     int cur[MV],pre[MV];
     15     bool used[MV],sign[MV];
     16     typef flow;
     17     typec cost,dist[MV];
     18     bool spfa(int s,int t) {
     19         mt(used,0);
     20         mt(sign,0);
     21         mt(dist,0);
     22         used[s]=sign[s]=true;
     23         while(!q.empty()) q.pop();
     24         q.push(s);
     25         while(!q.empty()) {
     26             int u=q.front();
     27             q.pop();
     28             used[u]=false;
     29             for(int i=g.head[u]; ~i; i=g.e[i].next) {
     30                 if(g.e[i].flow<1) continue;
     31                 int v=g.e[i].v;
     32                 typec c=g.e[i].cost;
     33                 if(!sign[v]||dist[v]>dist[u]+c) {
     34                     dist[v]=dist[u]+c;
     35                     sign[v]=true;
     36 
     37                     pre[v]=u;
     38                     cur[v]=i;
     39                     if(used[v]) continue;
     40                     used[v]=true;
     41                     q.push(v);
     42                 }
     43             }
     44         }
     45         return sign[t];
     46     } struct G {
     47         struct E {
     48             int v,next;
     49             typef flow;
     50             typec cost;
     51         } e[ME];
     52         int le,head[MV];
     53         void init() {
     54             le=0;
     55             mt(head,-1);
     56         } void add(int u,int v,typef flow,typec cost) {
     57             e[le].v=v;
     58             e[le].flow=flow;
     59             e[le].cost=cost;
     60             e[le].next=head[u];
     61             head[u]=le++;
     62         }
     63     } g;
     64 public:
     65     void init() {
     66         g.init();
     67     } void add(int u,int v,typef flow,typec cost) {
     68         g.add(u,v,flow,cost);
     69         g.add(v,u,0,-cost);
     70     } void solve(int s,int t) {
     71         flow=cost=0;
     72         while(spfa(s,t)) {
     73             int temp=t;
     74             typef now=inf;
     75             while(temp!=s) {
     76                 now=min(now,g.e[cur[temp]].flow);
     77 
     78                 temp=pre[temp];
     79             }
     80             flow+=now;
     81             temp=t;
     82             while(temp!=s) {
     83                 int id=cur[temp];
     84                 cost+=now*g.e[id].cost;
     85                 g.e[id].flow-=now;
     86                 g.e[id^1].flow+=now;
     87                 temp=pre[temp];
     88             }
     89         }
     90     } typef getflow() {
     91         return flow;
     92     } typec getcost() {
     93         return cost;
     94     }
     95 }mfmc;
     96 int a[M],b[M];
     97 int main() {
     98     int n,m,u,v;
     99     while(~scanf("%d%d",&n,&m)) {
    100         for(int i=1; i<=n; i++) {
    101             scanf("%d%d",&a[i],&b[i]);
    102         }
    103         mfmc.init();
    104         int s=0;
    105         int t=n+1;
    106         int sum=0;
    107         for(int i=1;i<=n;i++){
    108             if(a[i]>b[i]){
    109                 mfmc.add(s,i,a[i]-b[i],0);
    110             }
    111             else if(a[i]<b[i]){
    112                 mfmc.add(i,t,b[i]-a[i],0);
    113                 sum+=b[i]-a[i];
    114             }
    115         }
    116         while(m--) {
    117             scanf("%d%d",&u,&v);
    118             mfmc.add(u,v,inf,1);
    119             mfmc.add(v,u,inf,1);
    120         }
    121         mfmc.solve(s,t);
    122         int ans=-1;
    123         if(sum==mfmc.getflow()){
    124             ans=mfmc.getcost();
    125         }
    126         printf("%d
    ",ans);
    127     }
    128     return 0;
    129 }
    View Code

    end

  • 相关阅读:
    hdu 3068 最长回文
    Educational Codeforces Round 1 C. Nearest vectors
    Educational Codeforces Round 6 C. Pearls in a Row
    poj 3304 Segments
    Toy Storage
    poj 2318 TOYS
    CFA二级中文精讲(第2版)
    探秘大香格里拉
    巴西:热辣里约
    巴西:性感圣保罗
  • 原文地址:https://www.cnblogs.com/gaolzzxin/p/4678630.html
Copyright © 2011-2022 走看看