• NEU 1006 Intermediary


    1006: Intermediary

    时间限制: 1 Sec  内存限制: 128 MB
    提交: 261  解决: 25
    [提交][状态][讨论版]

    题目描述

    It is widely known that any two strangers can get to know each other through at most six other people. Now let’s prove this.

    In the country Intermediary Conducts Personal Communications (ICPC), there are up to n (2<=n<=100) ordinary people conveniently numbered from 0 to n-1. They don’t know each other, or, in other words, they are strangers. The only way they can communicate with each other is through the government, which, in fact, is an intermediary agency. The government consists of up to m (1<=m<=9) employees conveniently numbered from 0 to m-1. Suppose employee z can introduce person x to person y at a cost of d dollars. If this is the first time in a day that employee z introduce one person to another, he will only require d dollars. For the second time, he will require d dollars plus extra e dollars as his tip. For the third time and more, he will require d dollars plus extra f dollars. He is not dared to require any more than that since the strange country is somewhat democratic. And if person x is able to communicate with person t and person t is able to communicate with person y, then person t is always willing to transfer messages from person x to person y, at no charge. Of course, the intermediary fees are all paid by person x. Notice that employee z being able to introduce person x to person y doesn’t mean he can introduce person y to person x.

    Now person 0 has to send a message to person n-1 in one day. If all employees have just started to work, what is the minimum cost for person 0?

    输入

    For each test case, the first line contains three integers, n, m and q, where q is the number of intermediary relationships and q is at most 10,000. The second line has m integers, each indicating the value e of every employee, in the range [0, 100]. The third line has m integers too, each indicating the value f of every employee, in the range [e, 200]. The next q lines each contains four integers, x, y, z and d, indicating that employee z can introduce person x to person y requiring d dollars, where 1<=d<=200. There is a blank line after each test case.

    Proceed to the end of file.

    输出

    For each test case, print one integer on a single line, giving the minimum cost. If it is impossible, print -1.

    样例输入

    3 2 2
    1 1
    2 2
    0 1 0 1
    1 2 1 2
    
    5 1 4
    1
    2
    0 1 0 1
    1 2 0 1
    2 3 0 1
    3 4 0 1

    样例输出

    3
    9

    提示

     

    来源

    辽宁省赛2010

    题目描述:

    一个城市有n个人编号从0到n-1,m个中介编号从0到m-1,大家互相都不认识,必须通过中介来传递信息,不同中介在不同人之间传递信息收费不同(单向的,比如0号中介可以把1号居民的信息传递给2号居民,反过来不一定成立),每个中介在第一次传递信息不收取小费,第二次收取小费e,第三次及其以上收取小费f(不同的中介收费不同)。

    在这种情况下,0号居民想向n-1号居民传递一则信息,问最小花费多少。

    输入:

    多测试点,每个点的输入格式如下

    第一行n,m,q,表示居民数,中介数,和中介可以达成的传递种数

    第二行m个数代表每个中介的小费e

    第三行m个数代表每个中介的小费f

    第四行到第3+q行每行四个数字x,y,z,d,表示中介z可以传递居民x的信息给居民y,花费为d(没有加上小费)。

    输出:

    一行,一个数字,代表0号居民向n-1号居民传递一则信息的最小花费。

    思路:暴力搜索加最优化剪枝

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<iostream>
     4 using namespace std;
     5 int mid[10];
     6 int n,m,q;
     7 int E[10],F[10];
     8 int x,y,z,d;
     9 int lin[105],cnt;
    10 struct str
    11 {
    12     int next,y,z,d;
    13 }e[10005];
    14 void insertt()
    15 {
    16     e[++cnt].y=y;
    17     e[cnt].next=lin[x];
    18     lin[x]=cnt;
    19     e[cnt].z=z;
    20     e[cnt].d=d;
    21 }
    22 int vis[105];
    23 int ans,temp;
    24 void work(int x)
    25 {
    26     if(x==n-1)
    27     {
    28         ans=ans>temp?temp:ans;
    29         return ;
    30     }
    31     if(temp>=ans)return ;
    32     for(int i=lin[x];i;i=e[i].next)
    33     {
    34         if(!vis[e[i].y])
    35         {
    36             vis[e[i].y]=1;
    37             temp+=e[i].d;
    38             int tt=++mid[e[i].z];
    39             if(tt==2)temp+=E[e[i].z];
    40             else if(tt>2)temp+=F[e[i].z];
    41             work(e[i].y);
    42             if(tt==2)temp-=E[e[i].z];
    43             else if(tt>2)temp-=F[e[i].z];
    44             --mid[e[i].z];
    45             vis[e[i].y]=0;
    46             temp-=e[i].d;
    47         }
    48     }
    49 }
    50 int main()
    51 {
    52     while(scanf("%d%d%d",&n,&m,&q)!=EOF)
    53     {
    54         cnt=0;
    55         memset(e,0,sizeof(e));
    56         memset(lin,0,sizeof(lin));
    57         memset(mid,0,sizeof(mid));
    58         memset(vis,0,sizeof(vis));
    59         for(int i=0;i<m;i++)
    60             scanf("%d",&E[i]);
    61         for(int i=0;i<m;i++)
    62             scanf("%d",&F[i]);
    63         for(int i=0;i<q;i++)
    64         {
    65             scanf("%d%d%d%d",&x,&y,&z,&d);
    66             insertt();
    67         }
    68         ans=2000000000;
    69         temp=0;
    70         work(0);
    71         printf("%d
    ",ans);
    72     }
    73     return 0;
    74 }

    但是标称不是搜索,有点迷,不知道什么,先贴上来慢慢研究

      1 #include<cstring>
      2 
      3 #include<cstdio>
      4 
      5 #define __FILE_GENERATOR__
      6 struct Edge
      7 {
      8     int m,w,l;
      9     Edge *next;
     10 };
     11 int const INF=0x3fffffff;
     12 int const N=100,M=9,Q=10000;
     13 int const S=2000000; //开了hash
     14 int p3[M+1];
     15 Edge edges[Q];
     16 Edge *adj[N];
     17 int e[M],f[M];
     18 int ii[S],jj[S];
     19 int d[S];
     20 bool b[S];
     21 int n,m,q;
     22 int cnt,num;
     23 inline void initialize() //初始化
     24 {
     25     int k;
     26     p3[0]=1;
     27     for(k=1;k<=M;++k)
     28     p3[k]=p3[k-1]*3; //设计的hash算法
     29 }
     30 inline Edge* makeEdge(int m,int w,int l,Edge *next) //链式前向星结构
     31 {
     32     edges[cnt].m=m; //m是中间人编号
     33     edges[cnt].w=w; //w是 y
     34     edges[cnt].l=l; //l是花费
     35     edges[cnt].next=next;
     36     return &edges[cnt];
     37 }
     38 bool readin()
     39 {
     40     int x,y,z,d,k;
     41     if(scanf("%d%d%d",&n,&m,&q)==EOF)
     42     return false;
     43     for(k=0;k<m;++k)
     44     scanf("%d",&e[k]);
     45     for(k=0;k<m;++k)
     46     scanf("%d",&f[k]);
     47     for(k=0;k<n;++k)
     48     adj[k]=NULL;
     49     for(cnt=0;cnt<q;++cnt)
     50     {
     51         scanf("%d%d%d%d",&x,&y,&z,&d);
     52         adj[x]=makeEdge(z,y,d,adj[x]);
     53     }
     54     return true;
     55 }
     56 inline int D(int index)
     57 {
     58     return d[index];
     59 }
     60 void remove()
     61 {
     62     int x,y,z,r=1,pr,left,right;
     63     z=ii[num];
     64     ii[1]=z;
     65     jj[z]=1;
     66     --num;
     67     while((r<<1)<=num)
     68     {
     69         left=r<<1;
     70         right=(r<<1)+1;
     71         if(right<=num)
     72             pr=D(ii[left])<D(ii[right])?left:right;
     73         else
     74             pr=left;
     75         if(D(ii[r])<=D(ii[pr]))
     76             break;
     77         x=ii[r];
     78         y=ii[pr];
     79         ii[r]=y;
     80         jj[y]=r;
     81         ii[pr]=x;
     82         jj[x]=pr;
     83         r=pr;
     84     }
     85 }
     86 void adjust(int pr)
     87 {
     88     int x,y,r;
     89     while((pr>>1)>=1)
     90     {
     91         r=pr>>1;
     92         if(D(ii[r])<=D(ii[pr]))
     93             break;
     94         x=ii[r];
     95         y=ii[pr];
     96         ii[r]=y;
     97         jj[y]=r;
     98         ii[pr]=x;
     99         jj[x]=pr;
    100         pr=r;
    101     }
    102 }
    103 void solve()
    104 {
    105     int status,pstatus,nstatus,v,w,mid,t,l,k;
    106     Edge *pE;
    107     cnt=p3[m]*n;
    108     for(k=0;k<cnt;++k)
    109     {
    110         d[k]=INF;
    111         ii[k+1]=k;
    112         jj[k]=k+1;
    113     }
    114     memset(b,false,sizeof(b));
    115     num=cnt;
    116     d[0]=0;
    117     while(true)
    118     {
    119         if(num==0)
    120         {
    121             printf("-1\n");
    122             return;
    123         }
    124         pstatus=ii[1];
    125         if(d[pstatus]==INF)
    126         {
    127             printf("-1\n");
    128             return;
    129         }
    130         b[pstatus]=true;
    131         v=pstatus/p3[m];
    132         status=pstatus%p3[m];
    133         if(v==n-1)
    134         {
    135             printf("%d\n",d[pstatus]);
    136             return;
    137         }
    138         pE=adj[v];
    139         remove();
    140         while(pE!=NULL)
    141         {
    142             mid=pE->m;
    143             t=(status%p3[mid+1])/p3[mid];
    144             w=pE->w;
    145             l=pE->l;
    146             if(t==0)
    147             {
    148                 nstatus=status+p3[mid];
    149             }
    150             else if(t==1)
    151             {
    152                 l+=e[mid];
    153                 nstatus=status+p3[mid];
    154             }
    155             else if(t==2)
    156             {
    157                 l+=f[mid];
    158                 nstatus=status;
    159             }
    160             nstatus+=w*p3[m];
    161             if(!b[nstatus]&&d[pstatus]+l<d[nstatus])
    162             {
    163                 d[nstatus]=d[pstatus]+l;
    164                 adjust(jj[nstatus]);
    165             }
    166             pE=pE->next;
    167         }
    168     }
    169 }
    170 int main()
    171 {
    172     freopen("1006.in2","r",stdin);
    173     initialize();
    174     while(readin())
    175     solve();
    176     return 0;
    177 }
  • 相关阅读:
    websocket协议解决消息发送问题 Could not decode a text frame as UTF-8.
    成功解决internal/modules/cjs/loader.js:596 throw err; ^ Error: Cannot find module 'minimatch'
    FastDFS客户端与自定义文件存储系统
    fastdfs 中client.conf 文件
    centos 中 redis 的安装
    redis安装成功后get: command not found
    Shell基础知识(二)
    Shell基础知识(一)
    binary search模板总结
    配置远程jupyter notebook
  • 原文地址:https://www.cnblogs.com/xuwangzihao/p/4991361.html
Copyright © 2020-2023  润新知