zoukankan      html  css  js  c++  java
  • {white5}

    接着紫书图论开始刷。。。

    Fire!

     UVA - 11624 

    先从所有火源bfs1求出任意方格的起火时间,再从人开始bfs2逃跑。

      1 #include <bits/stdc++.h>
      2 using namespace std;
      3 const int maxn=1050;
      4 char pic[maxn][maxn];
      5 int vis[maxn][maxn];
      6 int dead[maxn][maxn];
      7 int n,m;
      8 int dir[4][2]={0,1,0,-1,1,0,-1,0};
      9 struct node
     10 {
     11     int x,y;
     12     int st;
     13     node(int x=0,int y=0,int st=0):x(x),y(y),st(st){}
     14 }now,nex;
     15 
     16 queue<node>q;
     17 bool inside(node no)
     18 {
     19     if(no.x>=0&&no.x<n&&no.y>=0&&no.y<m) return 1;
     20     return 0;
     21 }
     22 void bfs1()
     23 {
     24     memset(vis,0,sizeof(vis));
     25     while(!q.empty()) q.pop();
     26     for(int i=0;i<n;i++)
     27         for(int j=0;j<m;j++)
     28         {
     29             dead[i][j]=0x3f3f3f3f;
     30             if(pic[i][j]=='F')
     31             {
     32                 q.push(node(i,j,0));
     33                 dead[i][j]=0;
     34                 vis[i][j]=1;
     35             }
     36 
     37         }
     38     while(!q.empty())
     39     {
     40         now=q.front();
     41         q.pop();
     42         for(int i=0;i<4;i++)
     43         {
     44             nex.x=now.x+dir[i][0];
     45             nex.y=now.y+dir[i][1];
     46             if(inside(nex)&&!vis[nex.x][nex.y]&&pic[nex.x][nex.y]!='#')
     47             {
     48                 vis[nex.x][nex.y]=1;
     49                 dead[nex.x][nex.y]=dead[now.x][now.y]+1;
     50                 q.push(nex);
     51             }
     52         }
     53 
     54     }
     55     return ;
     56 }
     57 int bfs2()
     58 {
     59     while(!q.empty()) q.pop();
     60     memset(vis,0,sizeof(vis));
     61     for(int i=0;i<n;i++)
     62         for(int j=0;j<m;j++)
     63     if(pic[i][j]=='J')  {
     64         q.push(node(i,j,0));
     65         vis[i][j]=1;
     66         break;
     67     }
     68     while(!q.empty())
     69     {
     70         now=q.front();
     71         q.pop();
     72         if(now.x==0||now.x==n-1||now.y==0||now.y==m-1) return now.st+1;
     73         for(int i=0;i<4;i++)
     74         {
     75             nex.x=now.x+dir[i][0];
     76             nex.y=now.y+dir[i][1];
     77             nex.st=now.st+1;
     78             if(inside(nex)&&!vis[nex.x][nex.y]&&pic[nex.x][nex.y]!='#'&&nex.st<dead[nex.x][nex.y])
     79             {
     80                 vis[nex.x][nex.y]=1;
     81                 q.push(nex);
     82             }
     83         }
     84     }
     85     return -1;
     86 }
     87 int main()
     88 {
     89     int t;
     90     scanf("%d",&t);
     91     while(t--)
     92     {
     93         scanf("%d%d",&n,&m);
     94         for(int i=0;i<n;i++)
     95                 scanf("%s",pic[i]);
     96         bfs1();
     97         int ans=bfs2();
     98         if(ans!=-1) printf("%d
    ",ans);
     99         else puts("IMPOSSIBLE");
    100     }
    101 }
    View Code

    The Monocycle

     UVA - 10047 

     其实只是简单的一个bfs

    因为一点小错误搞了很久,代码也写得很拉杂。。。

    看到别人代码vis数组可以省去,dis可以直接放结构体里方便些

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 const int maxn=30;
     4 const int inf=0x3f3f3f3f;
     5 int d[maxn][maxn][4][5];
     6 int vis[maxn][maxn][4][5];
     7 int dir[4][2]={-1,0,0,1,1,0,0,-1};
     8 char g[maxn][maxn];
     9 int n,m;
    10 int sx,sy,ex,ey;
    11 struct node
    12 {
    13     int x,y,d,c;
    14     node(int x=0,int y=0,int d=0,int c=0):x(x),y(y),d(d),c(c){}
    15 };
    16 int bfs()
    17 {
    18     queue<node> q;
    19     for(int i=0;i<n;i++)
    20         for(int j=0;j<m;j++)
    21         for(int k=0;k<4;k++)
    22         for(int l=0;l<5;l++)
    23     {
    24         d[i][j][k][l]=inf;
    25         vis[i][j][k][l]=0;
    26     }
    27     d[sx][sy][0][0]=0;
    28     q.push(node(sx,sy,0,0));
    29     vis[sx][sy][0][0]=1;
    30     while(!q.empty())
    31     {
    32         node t=q.front();
    33         q.pop();
    34         if(t.x==ex&&t.y==ey&&t.c==0)
    35         {
    36             return d[ex][ey][t.d][0];
    37         }
    38         int dx=t.x+dir[t.d][0],dy=t.y+dir[t.d][1];
    39         int dd=t.d,dc=(t.c+1)%5;
    40         if(dx>=0&&dx<n&&dy>=0&&dy<m&&!vis[dx][dy][dd][dc]&&g[dx][dy]!='#')  //dc写成了dx找了半小时=_=||
    41         {
    42             d[dx][dy][dd][dc]=d[t.x][t.y][t.d][t.c]+1;
    43             vis[dx][dy][dd][dc]=1;
    44             q.push(node(dx,dy,dd,dc));
    45         }
    46         dx=t.x,dy=t.y;
    47         dd=(t.d+1)%4,dc=t.c;
    48         if(!vis[dx][dy][dd][dc])
    49         {
    50             d[dx][dy][dd][dc]=d[t.x][t.y][t.d][t.c]+1;
    51             vis[dx][dy][dd][dc]=1;
    52             q.push(node(dx,dy,dd,dc));
    53         }
    54         dx=t.x,dy=t.y;
    55         dd=(t.d-1+4)%4,dc=t.c;
    56          if(!vis[dx][dy][dd][dc])
    57         {
    58             d[dx][dy][dd][dc]=d[t.x][t.y][t.d][t.c]+1;
    59             vis[dx][dy][dd][dc]=1;
    60             q.push(node(dx,dy,dd,dc));
    61         }
    62     }
    63     return inf;
    64 }
    65 int main()
    66 {
    67     int kase=0;
    68     while(scanf("%d%d",&n,&m)&&(n||m))
    69     {
    70         for(int i=0;i<n;i++)
    71         {
    72             scanf("%s",g[i]);
    73             for(int j=0;j<m;j++){
    74                 if(g[i][j]=='S') {sx=i;sy=j;}
    75                 if(g[i][j]=='T') {ex=i;ey=j;}
    76             }
    77         }
    78         int ans=bfs();
    79         if(kase) puts("");
    80         printf("Case #%d
    ",++kase);
    81         if(ans!=inf) printf("minimum time = %d sec
    ",ans);
    82         else puts("destination not reachable");
    83     }
    84 
    85 }
    View Code

    The Necklace

     UVA - 10054 

    无向图的欧拉回路+输出路径

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 int g[55][55];
     4 int f[55];
     5 int deg[55];
     6 int n;
     7 
     8 int gf(int x)
     9 {
    10   return x==f[x]?x:f[x]=gf(f[x]);
    11 }
    12 
    13 void dfs(int u)
    14 {
    15     for(int i=1;i<=50;i++) if(g[u][i])
    16     {
    17         g[u][i]--;
    18         g[i][u]--;
    19         dfs(i);
    20         printf("%d %d
    ",i,u);
    21     }
    22 }
    23 int main()
    24 {
    25     int t;
    26     int kase=0;
    27     scanf("%d",&t);
    28     while(t--)
    29     {
    30         for(int i=0;i<=55;i++) f[i]=i;
    31         memset(deg,0,sizeof(deg));
    32         memset(g,0,sizeof(g));
    33         scanf("%d",&n);
    34         int u,v;
    35         for(int i=0;i<n;i++)
    36         {
    37             scanf("%d%d",&u,&v);
    38             g[u][v]++;
    39             g[v][u]++;
    40             deg[u]++;
    41             deg[v]++;
    42             int pu=gf(u);
    43             int pv=gf(v);
    44             if(pu!=pv) f[pu]=pv;
    45         }
    46         if(kase) puts("");
    47         printf("Case #%d
    ",++kase);
    48         int rt=0;
    49         int flag=1;
    50         for(int i=1;i<=50;i++) if(deg[i])
    51         {
    52             if(deg[i]&1) {
    53                 flag=0;
    54                 break;
    55             }
    56             if(rt==0) rt=gf(i);
    57             else{
    58                 int v=gf(i);
    59                 if(v!=rt) {
    60                     flag=0;
    61                     break;
    62                 }
    63             }
    64         }
    65         if(flag)
    66         {
    67             dfs(rt);
    68         }
    69         else puts("some beads may be lost");
    70     }
    71 }
    View Code

    Play on Words

     UVA - 10129 

    有向图欧拉路径

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<set>
     4 #include<iostream>
     5 #include<cctype>
     6 #include<string>
     7 #include<sstream>
     8 #include<algorithm>
     9 #include<map>
    10 #define LL long long
    11 using namespace std;
    12 const int maxn=100010;
    13 int in[30],out[30];
    14 int f[30];
    15 set<int> si;
    16 void init()
    17 {
    18     for(int i=0;i<30;i++)
    19     {
    20         in[i]=0;
    21         out[i]=0;
    22         f[i]=i;
    23     }
    24 }
    25 
    26 int gf(int x)
    27 {
    28     return x==f[x]?x:f[x]=gf(f[x]);
    29 }
    30 
    31 void uni(int a,int b)
    32 {
    33     int pa=gf(a);
    34     int pb=gf(b);
    35     f[pa]=pb;
    36 }
    37 string s;
    38 int main()
    39 {
    40     int t;
    41     scanf("%d",&t);
    42     while(t--)
    43     {
    44         int ok=1;
    45         si.clear();
    46         init();
    47         int n;
    48         int a,b;
    49         int ctin=0,ctout=0,ct=0;
    50         scanf("%d",&n);
    51         for(int i=0;i<n;i++)
    52         {
    53             cin>>s;
    54             a=s[0]-'a';
    55             b=s[s.length()-1]-'a';
    56             si.insert(a);
    57             si.insert(b);
    58             in[a]++;
    59             out[b]++;
    60             if(gf(a)!=gf(b)) uni(a,b);
    61         }
    62         int u=gf(a);
    63         for(set<int> ::iterator it=si.begin();it!=si.end();it++)
    64         {
    65             if(gf(*it)!=u) ct++;
    66             if(ct>0) {ok=0;break;}
    67             if(in[*it]-out[*it]==1) ctin++;
    68             else if(in[*it]-out[*it]==-1) ctout++;
    69             else if(in[*it]-out[*it]>1||in[*it]-out[*it]<-1) {ok=0;break;}
    70             if(ctin>1||ctout>1) {ok=0;break;}
    71         }
    72 
    73         if(ok) puts("Ordering is possible.");
    74         else puts("The door cannot be opened.");
    75     }
    76 }
    View Code

    连通分量


    Knights of the Round Table

     UVALive - 3523

    无向图的点的双联通分量

    二分图的判定

    题目要求的是不在任何一个奇圈上的人有几个

    先求出所有的点双联通分量,如果该分量不是二分图说明有奇圈,有奇圈就说明每个人都可以参加至少一场会议(p317有证明,不难),把这些人标记,最后拿总人数减去这些人就是答案了。

      1 #include <bits/stdc++.h>
      2 using namespace std;
      3 const int maxv=1010;
      4 const int maxe=1000010;
      5 
      6 int n,m;
      7 
      8 int g[maxv][maxv];
      9 struct Edge
     10 {
     11     int u,v,nex;
     12 }e[maxe<<1];
     13 int head[maxv];
     14 int cnt=0;
     15 void add(int u,int v)
     16 {
     17     e[cnt].u=u;
     18     e[cnt].v=v;
     19     e[cnt].nex=head[u];
     20     head[u]=cnt++;
     21 }
     22 void init()
     23 {
     24     memset(g,0,sizeof(g));
     25     memset(head,-1,sizeof(head));
     26     cnt=0;
     27 }
     28 
     29 int pre[maxv],iscut[maxv],bccno[maxv],dfsk,bcc_cnt;
     30 vector<int> bcc[maxv];
     31 stack<int> s;
     32 
     33 int dfs(int u,int f)
     34 {
     35     int lowu=pre[u]=++dfsk;
     36     int child=0;
     37     for(int i=head[u];i!=-1;i=e[i].nex)
     38     {
     39         int v=e[i].v;
     40         if(!pre[v])
     41         {
     42             s.push(i);
     43             child++;
     44             int lowv=dfs(v,u);
     45             lowu=min(lowu,lowv);
     46             if(lowv>=pre[u])
     47             {
     48                 iscut[u]=1;
     49                 bcc_cnt++;
     50                 bcc[bcc_cnt].clear(); //bcc从1开始编号
     51                 for(;;)
     52                 {
     53                     int te=s.top();
     54                     s.pop();
     55                     Edge p=e[te];
     56                     if(bccno[p.u]!=bcc_cnt) {bcc[bcc_cnt].push_back(p.u);bccno[p.u]=bcc_cnt; }
     57                     if(bccno[p.v]!=bcc_cnt) {bcc[bcc_cnt].push_back(p.v);bccno[p.v]=bcc_cnt; }
     58                     if(p.u==u&&p.v==v) break;
     59                 }
     60             }
     61         }
     62         else if(pre[v]<pre[u]&&v!=f)
     63         {
     64             s.push(i);
     65             lowu=min(lowu,pre[v]);
     66         }
     67     }
     68     if(f<0&&child==1) iscut[u]=0;
     69     return lowu;
     70 }
     71 
     72 void find_bcc(int n)
     73 {
     74     memset(pre,0,sizeof(pre));
     75     memset(iscut,0,sizeof(iscut));
     76     memset(bccno,0,sizeof(bccno));
     77     dfsk=bcc_cnt=0;
     78     for(int i=0;i<n;i++) if(!pre[i])
     79         dfs(i,-1);
     80 }
     81 
     82 int odd[maxv];  //是否可以参加会议
     83 int color[maxv];
     84 bool bipartite(int u,int b)
     85 {
     86     for(int i=head[u];i!=-1;i=e[i].nex)
     87     {
     88         int v=e[i].v;
     89         if(bccno[v]!=b) continue;
     90         if(color[u]==color[v]) return false;
     91         if(!color[v])
     92         {
     93             color[v]=3-color[u];
     94             if(!bipartite(v,b)) return false;
     95         }
     96     }
     97     return true;
     98 }
     99 int main()
    100 {
    101     
    102 
    103     while(scanf("%d%d",&n,&m)!=EOF&&(n||m))
    104     {
    105         init();
    106         int u,v;
    107         for(int i=0;i<m;i++){
    108             scanf("%d%d",&u,&v);
    109             u--;v--;
    110             g[u][v]=g[v][u]=1;
    111         }
    112         for(int i=0;i<n;i++)
    113             for(int j=i+1;j<n;j++) if(!g[i][j])
    114             {
    115                 add(i,j);
    116                 add(j,i);
    117             }
    118         find_bcc(n);
    119 
    120         memset(odd,0,sizeof(odd));
    121         for(int i=1;i<=bcc_cnt;i++)
    122         {
    123             memset(color,0,sizeof(color));
    124             for(int j=0;j<bcc[i].size();j++) bccno[bcc[i][j]]=i;
    125             int u=bcc[i][0];
    126             color[u]=1;
    127             if(!bipartite(u,i))
    128                 for(int j=0;j<bcc[i].size();j++) odd[bcc[i][j]]=1;
    129         }
    130         int ans=n;
    131         for(int i=0;i<n;i++) if(odd[i]) ans--;
    132         printf("%d
    ",ans);
    133     }
    134     return 0;
    135 }
    View Code

     下面这份代码有问题,,注释里写了

      1 #include <iostream>
      2 #include <cstring>
      3 #include <stack>
      4 #include <vector>
      5 #include <cstdio>
      6 using namespace std;
      7 const int maxv=1010;
      8 int A[maxv][maxv];
      9 int n,m;
     10 struct Edge
     11 {
     12     int u,v,nex;
     13 }e[maxv*maxv<<1];
     14 int head[maxv];
     15 int cnt=0;
     16 void init()
     17 {
     18     memset(head,-1,sizeof(head));
     19     cnt=0;
     20 }
     21 void add(int u,int v)
     22 {
     23     e[cnt].u=u;
     24     e[cnt].v=v;
     25     e[cnt].nex=head[u];
     26     head[u]=cnt++;
     27 }
     28 
     29 int pre[maxv],iscut[maxv],bccno[maxv],dfsk,bcc_cnt;
     30 stack<int> s;
     31 vector<int> bcc[maxv];
     32 
     33 int dfs(int u,int id)
     34 {
     35     int lowu=pre[u]=++dfsk;
     36     int child=0;
     37     for(int i=head[u];i!=-1;i=e[i].nex)
     38     {
     39         int v=e[i].v;
     40         if(i==(id^1)) continue;
     41         if(!pre[v])
     42         {
     43             child++;
     44             s.push(i);
     45             int lowv=dfs(v,id);
     46             lowu=min(lowv,lowu);
     47             if(lowv>=pre[u])  // 说明u是割顶
     48             {
     49                 iscut[u]=1;
     50                 bcc_cnt++;
     51                 bcc[bcc_cnt].clear();
     52                 for(;;)
     53                 {
     54                     Edge p=e[s.top()];
     55                     s.pop();
     56                     if(bccno[p.u]!=bcc_cnt) {bcc[bcc_cnt].push_back(p.u);bccno[p.u]=bcc_cnt;}
     57                     if(bccno[p.v]!=bcc_cnt) {bcc[bcc_cnt].push_back(p.v);bccno[p.v]=bcc_cnt;}
     58                     if(p.v==v&&p.u==u) break;
     59                 }
     60             }
     61         }
     62         else   if(pre[v]<pre[u])   //不加这一句就会错,,无解。。pre[v]难道不是一定小于pre[u]吗??
     63         {
     64             s.push(i);
     65             lowu=min(lowu,pre[v]);
     66         }
     67     }
     68     if(id<0&&child==1) iscut[u]=0;
     69     return lowu;
     70 }
     71 
     72 void find_bcc(int n)
     73 {
     74     memset(pre,0,sizeof(pre));
     75     memset(bccno,0,sizeof(bccno));
     76     memset(iscut,0,sizeof(iscut));
     77     dfsk=bcc_cnt=0;
     78     for(int i=0;i<n;i++) if(!pre[i]) dfs(i,-1);
     79 }
     80 int odd[maxv],color[maxv];
     81 int bigraph(int u,int b)
     82 {
     83     for(int i=head[u];i!=-1;i=e[i].nex)
     84     {
     85         int v=e[i].v;
     86         if(bccno[v]!=b) continue;
     87         if(color[v]==color[u]) return 0;
     88         if(!color[v])
     89         {
     90             color[v]=3-color[u];
     91             if(!bigraph(v,b)) return 0;
     92         }
     93     }
     94     return 1;
     95 }
     96 int main()
     97 {
     98     while(scanf("%d%d",&n,&m)&&(n||m))
     99     {
    100         init();
    101         int u,v;
    102         memset(A,0,sizeof(A));
    103         for(int i=0;i<m;i++)
    104         {
    105             scanf("%d%d",&u,&v);
    106             u--;v--;
    107             A[u][v]=A[v][u]=1;
    108         }
    109         for(int i=0;i<n;i++)
    110             for(int j=i+1;j<n;j++) if(!A[i][j])
    111             {
    112                 add(i,j);
    113                 add(j,i);
    114             }
    115 
    116         find_bcc(n);
    117 
    118         memset(odd,0,sizeof(odd));
    119         for(int i=1;i<=bcc_cnt;i++)
    120         {
    121             memset(color,0,sizeof(color));
    122             for(int j=0;j<bcc[i].size();j++) bccno[bcc[i][j]]=i;  //有可能某个点属于多个环
    123             int u=bcc[i][0];
    124             color[u]=1;
    125             if(!bigraph(u,i))  //不是二分图----有奇环----都可参加至少一次会议
    126                 for(int j=0;j<bcc[i].size();j++) odd[bcc[i][j]]=1;
    127         }
    128         int ans=n;
    129         for(int i=0;i<n;i++)
    130             if(odd[i]) ans--;
    131         printf("%d
    ",ans);
    132     }
    133 }
    View Code

    问题解决了,,pre[v]不一定小于pre[u],

    在一个环里,如果顺时针dfs的话,最后会有pre[v]<pre[u],然后倒推回去会把这个环加到同一个新的联通分量里

    接下来,按dfs接着走,会逆时针再去访问这个环,这时候会有pre[v]>pre[u],这种情况其实已经不能再把那条边压到栈里了,因为这个环已经记录过了,不用再处理


    Mining Your Own Business

     UVALive - 5135 

    无向图求割顶,,建图时总是忘记初始化。。。

      1 #include <bits/stdc++.h>
      2 using namespace std;
      3 #define LL long long
      4 const int maxv=1010;
      5 const int maxe=100010;
      6 
      7 int n,m;
      8 struct Edge
      9 {
     10     int u,v,nex;
     11 }e[maxe];
     12 int head[maxe]; //
     13 int cnt=0;
     14 void init()
     15 {
     16     memset(head,-1,sizeof(head));
     17     cnt=0;
     18 }
     19 void add(int u,int v)
     20 {
     21     e[cnt].u=u;
     22     e[cnt].v=v;
     23     e[cnt].nex=head[u];
     24     head[u]=cnt++;
     25 }
     26 
     27 int pre[maxe],bccno[maxe],iscut[maxe],dfsk,bcc_cnt;
     28 vector<int> bcc[maxe]; //边双联通分量
     29 stack<int> s;  //边号
     30 int dfs(int u,int f)
     31 {
     32     int lowu=pre[u]=++dfsk;
     33     int child=0;
     34     for(int i=head[u];i!=-1;i=e[i].nex)
     35     {
     36         int v=e[i].v;
     37         if(!pre[v])
     38         {
     39             s.push(i);
     40             child++;
     41             int lowv=dfs(v,u);
     42             lowu=min(lowu,lowv);
     43             if(lowv>=pre[u])
     44             {
     45                 iscut[u]=1;
     46                 bcc_cnt++;
     47                 bcc[bcc_cnt].clear();
     48                 for(;;)
     49                 {
     50                     int te=s.top();
     51                     s.pop();
     52                     Edge p=e[te];
     53                     if(bccno[p.u]!=bcc_cnt) {bcc[bcc_cnt].push_back(p.u); bccno[p.u]=bcc_cnt;}
     54                     if(bccno[p.v]!=bcc_cnt) {bcc[bcc_cnt].push_back(p.v); bccno[p.v]=bcc_cnt;}
     55                     if(p.u==u&&p.v==v) break;
     56                 }
     57             }
     58         }
     59         else if(pre[v]<pre[u]&&v!=f)
     60         {
     61             s.push(i);
     62             lowu=min(pre[v],lowu);
     63         }
     64     }
     65     if(f<0&&child==1) iscut[u]=0;
     66     return lowu;
     67 }
     68 
     69 void find_bcc(int n)
     70 {
     71     memset(pre,0,sizeof(pre));
     72     memset(bccno,0,sizeof(bccno));
     73     memset(iscut,0,sizeof(iscut));
     74     dfsk=bcc_cnt=0;
     75     for(int i=0;i<n;i++) if(!pre[i])
     76         dfs(i,-1);
     77 }
     78 
     79 int main()
     80 {
     81     int kase=0;
     82    // freopen("in.txt","r",stdin);
     83     while(scanf("%d",&m)&&m)
     84     {
     85         n=0;
     86         init();
     87         int u,v;
     88         for(int i=0;i<m;i++)
     89         {
     90             scanf("%d%d",&u,&v);
     91             u--;v--;
     92             add(u,v);
     93             add(v,u);
     94             n=max(n,max(u,v));
     95         }
     96         find_bcc(n);
     97         LL ans1=0,ans2=1;
     98         for(int i=1;i<=bcc_cnt;i++)
     99         {
    100             int cut_cnt=0;
    101             for(int j=0;j<bcc[i].size();j++)
    102                 if(iscut[bcc[i][j]]) cut_cnt++; //统计bcc中割顶数目
    103             if(cut_cnt==1)
    104             {
    105                 ans1++;
    106                 ans2*=(long long)(bcc[i].size()-1);
    107             }
    108         }
    109         if(bcc_cnt==1)
    110         {
    111             ans1=2;
    112             ans2=bcc[1].size()*(bcc[1].size()-1)/2;
    113         }
    114         printf("Case %d: %lld %lld
    ",++kase,ans1,ans2);
    115     }
    116 }
    View Code

    Proving Equivalences

     UVALive - 4287 

    有向图,求双联通分量,然后再把每个联通分量缩成一个点

    当每个点都有入有出时才成为双联通(不知道怎么描述,等想清楚了再回来写)

    ans=max(a,b);

      1 #include <bits/stdc++.h>
      2 using namespace std;
      3 const int maxv=20010;
      4 const int maxe=50010;
      5 
      6 int n,m;
      7 
      8 struct Edge
      9 {
     10     int u,v,nex;
     11 }e[maxe<<1];
     12 int head[maxv];
     13 int cnt=0;
     14 void init()
     15 {
     16     memset(head,-1,sizeof(head));
     17     cnt=0;
     18 }
     19 void add(int u,int v)
     20 {
     21     e[cnt].u=u;
     22     e[cnt].v=v;
     23     e[cnt].nex=head[u];
     24     head[u]=cnt++;
     25 }
     26 
     27 int pre[maxv],sccno[maxv],lowlink[maxv],dfsk,scc_cnt;
     28 stack<int> s;
     29 
     30 void dfs(int u)
     31 {
     32     pre[u]=lowlink[u]=++dfsk;
     33     s.push(u);
     34     for(int i=head[u];i!=-1;i=e[i].nex)
     35     {
     36         int v=e[i].v;
     37         if(!pre[v])
     38         {
     39             dfs(v);
     40             lowlink[u]=min(lowlink[u],lowlink[v]);
     41         }
     42         else if(!sccno[v])
     43             lowlink[u]=min(lowlink[u],lowlink[v]);
     44     }
     45     if(lowlink[u]==pre[u])
     46     {
     47         scc_cnt++;
     48         for(;;)
     49         {
     50             int x=s.top();
     51             s.pop();
     52             sccno[x]=scc_cnt;
     53             if(x==u) break;
     54         }
     55     }
     56 }
     57 
     58 void find_scc(int n)
     59 {
     60     dfsk=scc_cnt=0;
     61     memset(sccno,0,sizeof(sccno));
     62     memset(pre,0,sizeof(pre));
     63     for(int i=0;i<n;i++) if(!pre[i])
     64         dfs(i);
     65 }
     66 int in0[maxv],out0[maxv];
     67 
     68 int main()
     69 {
     70     int t;
     71     scanf("%d",&t);
     72     while(t--)
     73     {
     74         init();
     75         scanf("%d%d",&n,&m);
     76         for(int i=0;i<m;i++)
     77         {
     78             int u,v;
     79             scanf("%d%d",&u,&v);
     80             u--;v--;
     81             add(u,v);
     82         }
     83 
     84         find_scc(n);
     85 
     86         for(int i=1;i<=scc_cnt;i++) in0[i]=out0[i]=1;
     87         for(int u=0;u<n;u++)
     88             for(int i=head[u];i!=-1;i=e[i].nex)
     89         {
     90             int v=e[i].v;
     91             if(sccno[v]!=sccno[u]) in0[sccno[v]]=out0[sccno[u]]=0;
     92         }
     93         int a=0,b=0;
     94         for(int i=1;i<=scc_cnt;i++)
     95         {
     96             if(in0[i]) a++;
     97             if(out0[i]) b++;
     98         }
     99         int ans=max(a,b);
    100         if(scc_cnt==1) ans=0;
    101         printf("%d
    ",ans);
    102     }
    103     return 0;
    104 }
    View Code

    The Largest Clique

     UVA - 11324 
    先求出SCC,然后缩点,就变成了一个DAG,每个点的权值为内点的个数,用DP求解最大值。
     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 const int maxv=1010;
     4 
     5 int n,m;
     6 
     7 vector<int> G[maxv];
     8 int pre[maxv],lowlink[maxv],sccno[maxv],dfsk,scc_cnt;
     9 stack<int> s;
    10 
    11 void dfs(int u)
    12 {
    13     pre[u]=lowlink[u]=++dfsk;
    14     s.push(u);
    15     for(int i=0;i<G[u].size();i++)
    16     {
    17         int v=G[u][i];
    18         if(!pre[v])
    19         {
    20             dfs(v);
    21             lowlink[u]=min(lowlink[u],lowlink[v]);
    22         }
    23         else if(!sccno[v]) lowlink[u]=min(lowlink[u],lowlink[v]);
    24     }
    25     if(lowlink[u]==pre[u])
    26     {
    27         scc_cnt++;
    28         for(;;)
    29         {
    30             int x=s.top();
    31             s.pop();
    32             sccno[x]=scc_cnt;
    33             if(x==u) break;
    34         }
    35     }
    36 }
    37 void find_scc(int n)
    38 {
    39     memset(pre,0,sizeof(pre));
    40     memset(lowlink,0,sizeof(lowlink));
    41     memset(sccno,0,sizeof(sccno));
    42     dfsk=scc_cnt=0;
    43     for(int i=0;i<n;i++) if(!pre[i])
    44         dfs(i);
    45 }
    46 
    47 int sz[maxv],d[maxv],TG[maxv][maxv];  //DP
    48 int dp(int u)
    49 {
    50     if(d[u]>0) return d[u];
    51     d[u]=sz[u];
    52     for(int i=1;i<=scc_cnt;i++)
    53         if(TG[u][i]&&u!=i) d[u]=max(d[u],dp(i)+sz[u]);
    54     return d[u];
    55 }
    56 int main()
    57 {
    58     int t;
    59     scanf("%d",&t);
    60     while(t--)
    61     {
    62         scanf("%d%d",&n,&m);
    63         for(int i=0;i<n;i++) G[i].clear();
    64         int u,v;
    65         for(int i=0;i<m;i++)
    66         {
    67             scanf("%d%d",&u,&v);
    68             u--;v--;
    69             G[u].push_back(v);
    70         }
    71         find_scc(n);
    72 
    73         //DP
    74         memset(d,-1,sizeof(d));
    75         memset(sz,0,sizeof(sz));
    76         memset(TG,0,sizeof(TG));
    77         for(int i=0;i<n;i++)
    78         {
    79             sz[sccno[i]]++;
    80             for(int j=0;j<G[i].size();j++)
    81             TG[sccno[i]][sccno[G[i][j]]]=1;
    82         }
    83         int ans=0;
    84         for(int i=1;i<=scc_cnt;i++)
    85             ans=max(ans,dp(i));
    86         printf("%d
    ",ans);
    87     }
    88 }
    COPY

    Now or later

     UVALive - 3211 

     2sat

    第一次接触是大一刚开学不久的离散课上老师提到的,神奇orz

    下面是lrj书上的模板

     ▄█▀█●
     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 const int maxn=2010;
     4 struct TwoSAT
     5 {
     6     int n;
     7     vector<int> G[maxn<<1];
     8     bool mark[maxn<<1];
     9     int s[maxn<<1],c;
    10 
    11     bool dfs(int x)
    12     {
    13         if(mark[x^1]) return false;
    14         if(mark[x]) return true;
    15         mark[x]=true;
    16         s[c++]=x;
    17         for(int i=0;i<G[x].size();i++)
    18             if(!dfs(G[x][i])) return false;
    19         return true;
    20     }
    21 
    22     void init(int n)
    23     {
    24         this->n=n;
    25         for(int i=0;i<n*2;i++) G[i].clear();
    26         memset(mark,0,sizeof(mark));
    27     }
    28 
    29     void add_clause(int x,int xv,int y,int yv)
    30     {
    31         x=x*2+xv;
    32         y=y*2+yv;
    33         G[x^1].push_back(y);
    34         G[y^1].push_back(x);
    35     }
    36 
    37     bool solve()
    38     {
    39         for(int i=0;i<n*2;i+=2)
    40             if(!mark[i]&&!mark[i^1])
    41             {
    42                 c=0;
    43                 if(!dfs(i))
    44                 {
    45                     while(c>0) mark[s[--c]]=false;
    46                     if(!dfs(i+1)) return false;
    47                 }
    48             }
    49         return true;
    50     }
    51 }solver;
    52 int n;
    53 int T[maxn][2];
    54 
    55 bool test(int diff)
    56 {
    57     solver.init(n);
    58     for(int i=0;i<n;i++) for(int a=0;a<2;a++)
    59         for(int j=i+1;j<n;j++) for(int b=0;b<2;b++)
    60         if(abs(T[i][a]-T[j][b])<diff) solver.add_clause(i,a^1,j,b^1);
    61     return solver.solve();
    62 }
    63 
    64 int main()
    65 {
    66     while(scanf("%d",&n)==1&&n)
    67     {
    68         int L=0,R=0;
    69         for(int i=0;i<n;i++) for(int a=0;a<2;a++)
    70         {
    71             scanf("%d",&T[i][a]);
    72             R=max(R,T[i][a]);
    73         }
    74         while(L<R)
    75         {
    76             int M=(R-L+1)/2+L;
    77             if(test(M)) L=M;
    78             else R=M-1;
    79         }
    80         printf("%d
    ",L);
    81     }
    82     return 0;
    83 
    84 
    85 }
    LRJ

    Astronauts

     UVALive - 3713 

     还是2sat,,模板好用啊 ▄█▀█●

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 const int maxn=100010;
     4 struct TwoSAT
     5 {
     6     int n;
     7     vector<int> G[maxn<<1];
     8     bool mark[maxn<<1];
     9     int s[maxn<<1],c;
    10 
    11     bool dfs(int x)
    12     {
    13         if(mark[x^1]) return false;
    14         if(mark[x]) return true;
    15         mark[x]=true;
    16         s[c++]=x;
    17         for(int i=0;i<G[x].size();i++)
    18             if(!dfs(G[x][i])) return false;
    19         return true;
    20     }
    21 
    22     void init(int n)
    23     {
    24         this->n=n;
    25         for(int i=0;i<n*2;i++) G[i].clear();
    26         memset(mark,0,sizeof(mark));
    27     }
    28 
    29     void add_clause(int x,int xv,int y,int yv)
    30     {
    31         x=x*2+xv;
    32         y=y*2+yv;
    33         G[x^1].push_back(y);
    34         G[y^1].push_back(x);
    35     }
    36 
    37     bool solve()
    38     {
    39         for(int i=0;i<n*2;i+=2)
    40             if(!mark[i]&&!mark[i^1])
    41             {
    42                 c=0;
    43                 if(!dfs(i))
    44                 {
    45                     while(c>0) mark[s[--c]]=false;
    46                     if(!dfs(i+1)) return false;
    47                 }
    48             }
    49         return true;
    50     }
    51 }solver;
    52 int n,m;
    53 int age[maxn],sum;
    54 
    55 bool check(int x)
    56 {
    57     return age[x]*n<sum;
    58 }
    59 
    60 int main()
    61 {
    62     while(scanf("%d%d",&n,&m)!=EOF&&(n||m))
    63     {
    64         sum=0;
    65         for(int i=0;i<n;i++) {
    66             scanf("%d",&age[i]);
    67             sum+=age[i];
    68         }
    69         solver.init(n);
    70         for(int i=0;i<m;i++)
    71         {
    72             int a,b;
    73             scanf("%d%d",&a,&b);
    74             a--;b--;
    75             solver.add_clause(a,1,b,1);
    76             if(check(a)==check(b)) solver.add_clause(a,0,b,0);
    77         }
    78         if(!solver.solve()) printf("No solution
    ");
    79         else {
    80             for(int i=0;i<n;i++)
    81             if(solver.mark[i*2]) printf("C
    ");
    82             else if(check(i)) puts("B");
    83             else puts("A");
    84         }
    85     }
    86     return 0;
    87 
    88 
    89 }
    View Code

    最短路:


    Airport Express

     UVA - 11374

    怎么说呢,,看了一个人的代码,里面有一点小错误,搞了很久才发现,这种人太不负责任了,贴代码也要有原则的吧=_=||

    算是对输出路径有了更深的理解

      1 #include <bits/stdc++.h>
      2 using namespace std;
      3 const int inf=0x3f3f3f3f;
      4 const int maxv=1010;
      5 const int maxe=1010;
      6 
      7 struct Edge
      8 {
      9     int u,v,w;
     10     int nex;
     11 }e[maxe<<1];
     12 int head[maxv];
     13 int cnt=0;
     14 void init()
     15 {
     16     memset(head,-1,sizeof(head));
     17     cnt=0;
     18 }
     19 void add(int u,int v,int w)
     20 {
     21     e[cnt].u=u;
     22     e[cnt].v=v;
     23     e[cnt].w=w;
     24     e[cnt].nex=head[u];
     25     head[u]=cnt++;
     26 }
     27 
     28 typedef pair<int,int> PII;
     29 int dis[maxv];
     30 int par[maxv];
     31 void dijkstra(int s)
     32 {
     33     priority_queue<PII,vector<PII>,greater<PII> > pq;
     34     for(int i=0;i<maxv;i++) dis[i]=inf;
     35     dis[s]=0;
     36     pq.push(PII(0,s));
     37     while(!pq.empty())
     38     {
     39         PII temp=pq.top();
     40         pq.pop();
     41         int u=temp.second;
     42         if(dis[u]<temp.first) continue;
     43         for(int i=head[u];i!=-1;i=e[i].nex)
     44         {
     45             if(dis[e[i].v]>dis[u]+e[i].w)
     46             {
     47                 dis[e[i].v]=dis[u]+e[i].w;
     48                 par[e[i].v]=i;
     49                 pq.push(PII(dis[e[i].v],e[i].v));
     50             }
     51         }
     52     }
     53 }
     54 int n,ss,ee;
     55 int ds[maxv],de[maxv];
     56 int p[maxv],p1[maxv];
     57 
     58 void print(int a)
     59 {
     60     if(a==ss)
     61     {
     62         printf("%d",a+1);
     63     }
     64     else
     65     {
     66         int x=p1[a];
     67         print(e[x].u);
     68         printf(" %d",a+1);
     69     }
     70     return ;
     71 }
     72 
     73 int main()
     74 {
     75     int kase=0;
     76 
     77     while(scanf("%d%d%d",&n,&ss,&ee)!=EOF&&n)
     78     {
     79         if(kase++) puts("");
     80         ss--;ee--;
     81         init();
     82         int u,v,w;
     83         int m;
     84         scanf("%d",&m);
     85         for(int i=0;i<m;i++)
     86         {
     87             scanf("%d%d%d",&u,&v,&w);
     88             u--,v--;
     89             add(u,v,w);
     90             add(v,u,w);
     91         }
     92         dijkstra(ss);
     93         for(int i=0;i<n;i++) {ds[i]=dis[i];p1[i]=par[i];}
     94         pa[ss]=-1;
     95         dijkstra(ee);
     96         for(int i=0;i<n;i++) {de[i]=dis[i];p[i]=par[i];}
     97         p[ee]=-1;
     98 
     99 
    100         int ans1=ds[ee];
    101         int a=-1,b=-1;
    102         int k;
    103         scanf("%d",&k);
    104         for(int i=0;i<k;i++)
    105         {
    106             scanf("%d%d%d",&u,&v,&w);
    107             u--;v--;
    108             if(ans1>ds[u]+w+de[v])
    109             {
    110                 ans1=ds[u]+w+de[v];
    111                 a=u,b=v;
    112             }
    113             if(ans1>ds[v]+w+de[u])
    114             {
    115                 ans1=ds[v]+w+de[u];
    116                 a=v,b=u;
    117             }
    118         }
    119 
    120         int flag=0;
    121         if(a==-1)
    122         {
    123             int x=ss;
    124             while(x!=ee)
    125             {
    126                 if(!flag){printf("%d",x+1);flag=1;}
    127                 else printf(" %d",x+1);
    128                 x=e[p[x]].u;
    129             }
    130             printf(" %d
    ",ee+1);
    131             printf("Ticket Not Used
    %d
    ",ans1);
    132         }
    133         else
    134         {
    135             print(a);
    136             int x=b;
    137             while(x!=ee)
    138             {
    139                 printf(" %d",x+1);
    140                 x=e[p[x]].u;
    141             }
    142             printf(" %d
    ",ee+1);
    143             printf("%d
    %d
    ",a+1,ans1);
    144         }
    145     }
    146     return 0;
    147 }
    View Code

    Walk Through the Forest

     UVA - 10917

    最短路树,DP求解

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 const int inf=0x3f3f3f3f;
     4 const int maxv=1010;
     5 const int maxe=1000010; //??
     6 int n,m;
     7 struct Edge
     8 {
     9     int u,v,w;
    10     int nex;
    11 }e[maxe<<1];
    12 int head[maxv];
    13 int cnt=0;
    14 void init()
    15 {
    16     memset(head,-1,sizeof(head));
    17     cnt=0;
    18 }
    19 void add(int u,int v,int w)
    20 {
    21     e[cnt].u=u;
    22     e[cnt].v=v;
    23     e[cnt].w=w;
    24     e[cnt].nex=head[u];
    25     head[u]=cnt++;
    26 }
    27 typedef pair<int,int> PII;
    28 int dis[maxv],par[maxv];
    29 void dijkstra(int s)
    30 {
    31     priority_queue<PII,vector<PII>,greater<PII> > pq;
    32     for(int i=0;i<maxv;i++) dis[i]=inf;
    33     dis[s]=0;
    34     pq.push(PII(0,s));
    35     while(!pq.empty())
    36     {
    37         PII temp=pq.top();
    38         pq.pop();
    39         int u=temp.second;
    40         if(dis[u]<temp.first) continue;
    41         for(int i=head[u];i!=-1;i=e[i].nex)
    42         {
    43             int v=e[i].v;
    44             if(dis[v]>dis[u]+e[i].w)
    45             {
    46                 dis[v]=dis[u]+e[i].w;
    47                 par[v]=i;
    48                 pq.push(PII(dis[v],v));
    49             }
    50         }
    51     }
    52 }
    53 int dp[maxv];
    54 int DP(int u)
    55 {
    56     if(u==1) return 1;
    57     if(dp[u]!=-1) return dp[u];
    58     dp[u]=0;
    59     for(int i=head[u];i!=-1;i=e[i].nex)
    60     {
    61         int v=e[i].v;
    62         if(dis[v]<dis[u]) dp[u]+=DP(v);
    63     }
    64     return dp[u];
    65 }
    66 int main()
    67 {
    68     while(scanf("%d",&n)&&n)
    69     {
    70         scanf("%d",&m);
    71         init();
    72         int u,v,w;
    73         for(int i=0;i<m;i++)
    74         {
    75             scanf("%d%d%d",&u,&v,&w);
    76             u--;v--;
    77             add(u,v,w);
    78             add(v,u,w);
    79         }
    80         dijkstra(1);
    81         memset(dp,-1,sizeof(dp));
    82         int ans=DP(0);
    83         printf("%d
    ",ans);
    84     }
    85 
    86 }
    View Code

    Warfare And Logistics

     UVALive - 4080 

    怎么今天总是踩到各种坑里=_=||

    没有原题,,lrj书上说1000条边,可是我开到1000各种WA了n次

    别人也是1000就过了orz。。我得开到2000才能过

    无解,,看不出来代码哪里有问题

    【如果每次删除一条边,要跑m次dijkstra,其实其中很多次都对最短路没有影响,因为删掉的边不在最短路里】

    【因此,可以每次删除最短路树中的一条边,需要跑n次,复杂度降低到可接受程度】


     再补充一点补码的知识,上学期学过可是已经忘了,刚刚翻得书=_=||

    正数的补码简单,直接写成二进制形式即可

    对于负数,先写出对应的正数的补码,然后右边起到第一位不是0的这些位不变,其它位取反,即是负数的补码

    比如  -3的补码为  0000 0011——》1111 1101

      所以-3取反之后就变成了0000 0010,即2

    在用前向星存边时,从0开始,那么i与i^1是一对边,i是正向,i^1是反向

    如果要求某条边i的正向边怎么求呢?只需要(i&(-2))即得到正向边

    因为-2的补码为11111110,(i&(-2))即把最右那位置0,其它位不变,得到的就是正向边了

      1 #include <bits/stdc++.h>
      2 #define LL long long
      3 using namespace std;
      4 const int inf=0x3f3f3f3f;
      5 const int maxv=110;
      6 const int maxe=2010;
      7 int n,m,L;
      8 struct Edge
      9 {
     10     int u,v,w;
     11     int nex;
     12 }e[maxe<<1];
     13 int head[maxv];
     14 int cnt=0;
     15 void init()
     16 {
     17     memset(head,-1,sizeof(head));
     18     cnt=0;
     19 }
     20 void add(int u,int v,int w)
     21 {
     22     e[cnt].u=u;
     23     e[cnt].v=v;
     24     e[cnt].w=w;
     25     e[cnt].nex=head[u];
     26     head[u]=cnt++;
     27 }
     28 
     29 typedef pair<int,int> PII;
     30 int dis[maxv],par[maxv];
     31 void dijkstra(int s,bool c,int e1)
     32 {
     33     priority_queue<PII,vector<PII>,greater<PII> > pq;
     34     for(int i=0;i<maxv;i++) dis[i]=L;
     35     dis[s]=0;
     36     pq.push(PII(0,s));
     37     par[s]=-1;
     38     while(!pq.empty())
     39     {
     40         PII t=pq.top();
     41         pq.pop();
     42         int u=t.second;
     43         if(dis[u]<t.first) continue;
     44         for(int i=head[u];i!=-1;i=e[i].nex)
     45         {
     46             if(i==e1||i==(e1^1)) continue;   //
     47             int v=e[i].v;
     48             if(dis[v]>dis[u]+e[i].w)
     49             {
     50                 dis[v]=dis[u]+e[i].w;
     51                 if(c) par[v]=i;
     52                 pq.push(PII(dis[v],v));
     53             }
     54         }
     55     }
     56 }
     57 LL cal()
     58 {
     59     LL temp=0;
     60     for(int i=0;i<n;i++)
     61         temp+=dis[i];
     62     return temp;
     63 }
     64 vector<int> vv;
     65 int delta[maxe];
     66 
     67 int main()
     68 {
     69     while(scanf("%d%d%d",&n,&m,&L)!=EOF)
     70     {
     71         init();
     72         int u,v,w;
     73         for(int i=0;i<m;i++)
     74         {
     75             scanf("%d%d%d",&u,&v,&w);
     76             u--;v--;
     77             add(u,v,w);
     78             add(v,u,w);
     79         }
     80         LL ans=0;
     81         vv.clear();
     82         memset(delta,0,sizeof(delta));
     83         for(int i=0;i<n;i++)
     84         {
     85             dijkstra(i,1,-1);
     86             LL temp=cal();
     87             ans+=temp;
     88             for(int j=0;j<n;j++)
     89                 if(par[j]!=-1)
     90             {
     91                 dijkstra(i,0,par[j]);
     92                 int id=par[j]&(~1);   //
     93                 if(!delta[id]) vv.push_back(id);
     94                 delta[id]+=cal()-temp;
     95             }
     96 
     97         }
     98         int maxdelta=0;
     99         for(int i=0;i<(int)vv.size();i++)
    100             maxdelta=max(maxdelta,delta[vv[i]]);
    101         printf("%lld %lld
    ",ans,ans+maxdelta);
    102     }
    103 }
    View Code

     附上大佬代码

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 
     4 const int maxn = 102, maxm = 2002;
     5 int head[maxn], to[maxm], nxt[maxm],wei[maxm],ecnt;
     6 int delta[maxm];
     7 
     8 void addEdge(int u,int v,int w)
     9 {
    10     to[ecnt] = v;
    11     nxt[ecnt] = head[u];
    12     wei[ecnt] = w;
    13     head[u] = ecnt++;
    14 }
    15 
    16 typedef pair<int,int> Node;
    17 #define fi first
    18 #define se second
    19 
    20 int d[maxn],pa[maxn];
    21 typedef long long ll;
    22 
    23 void dijkstra(int n,int s,int L,bool flag,int e1,int e2)// e1 e2 边应该忽略
    24 {
    25     priority_queue<Node,vector<Node>,greater<Node> > q;
    26     fill(d,d+n,L);
    27     d[s] = 0; q.push(Node(0,s)); pa[s] = -1;
    28     while(q.size()){
    29         Node x = q.top(); q.pop();
    30         int u = x.se;
    31         if(x.fi != d[u]) continue;
    32         for(int i = head[u]; ~i; i = nxt[i])if(i!=e1 && i!=e2) {
    33             int v = to[i];
    34             if(d[v] > d[u]+wei[i]){
    35                 d[v] = d[u]+wei[i];
    36                 if(flag) pa[v] = i; // 入边编号
    37                 q.push(Node(d[v],v));
    38             }
    39         }
    40     }
    41 }
    42 
    43 ll cal(int n)
    44 {
    45     ll ret = 0;
    46     for(int i = 0; i < n; i++){
    47         ret += d[i];
    48     }
    49     return ret;
    50 }
    51 
    52 
    53 void init()
    54 {
    55     memset(head,-1,sizeof(head));
    56     ecnt = 0;
    57     memset(delta,0,sizeof(delta));
    58 }
    59 
    60 int main()
    61 {
    62     //freopen("in.txt","r",stdin);
    63     int n,m,L;
    64     while(~scanf("%d%d%d",&n,&m,&L)){
    65         init();
    66          while(m--){
    67             int u,v,w; scanf("%d%d%d",&u,&v,&w);
    68             addEdge(--u,--v,w); addEdge(v,u,w);
    69         }
    70         ll ans1 = 0;
    71         vector<int> edges;
    72         for(int u = 0; u < n; u++){
    73             dijkstra(n,u,L,true,-1,-1);
    74             ll t  = cal(n);
    75             ans1 += t;
    76             for(int i = 0; i < n; i++){
    77                 if(~pa[i]){
    78                     dijkstra(n,u,L,false,pa[i],pa[i]^1);
    79                     int eid = pa[i]&(~1);
    80                     if(!delta[eid]) edges.push_back(eid);
    81                     delta[eid] += cal(n)-t;
    82                 }
    83             }
    84         }
    85         int MaxDelta = 0;
    86         for(int i = 0; i < (int)edges.size(); i++){
    87             MaxDelta = max(MaxDelta,delta[edges[i]]);
    88         }
    89         printf("%lld %lld
    ",ans1,ans1+MaxDelta);
    90     }
    91     return 0;
    92 }
    View Code

    The Toll! Revisited

     UVA - 10537

    不想做了,,先贴上LRJ代码,日后再做

     1 // UVa10537 Toll! Revisited
     2 // Rujia Liu
     3 #include<cstdio>
     4 #include<cstring>
     5 #include<algorithm>
     6 using namespace std;
     7 
     8 const int maxn = 52 + 10;
     9 const long long INF = 1LL << 60;
    10 typedef long long LL;
    11 
    12 int n, G[maxn][maxn], src, dest, p;
    13 int mark[maxn]; // 标记
    14 LL d[maxn];     // d[i]表示从点i出发(已经交过点i的税了)时至少要带多少东西,到dest时还能剩p个东西
    15 
    16 int read_node() {
    17   char ch[9];
    18   scanf("%s", ch);
    19   if(ch[0] >= 'A' && ch[0] <= 'Z') return ch[0] - 'A';
    20   else return ch[0] - 'a' + 26;
    21 }
    22 
    23 char format_node(int u) {
    24   return u < 26 ? 'A' + u : 'a' + (u - 26);
    25 }
    26 
    27 // 拿着item个东西去结点next,还剩多少个东西
    28 LL forward(LL item, int next) {
    29   if(next < 26) return item - (item + 19) / 20;
    30   return item - 1;
    31 }
    32 
    33 // 至少要拿着多少个东西到达结点u,交税以后还能剩d[u]个东西
    34 // 为了使代码容易理解,这里使用一种不太数学的解法
    35 LL back(int u) {
    36   if(u >= 26) return d[u]+1;
    37   LL X = d[u] * 20 / 19; // 初始值
    38   while(forward(X, u) < d[u]) X++; // 调整
    39   return X;
    40 }
    41 
    42 void solve() {
    43   n = 52; // 总是有52个结点
    44   memset(mark, 0, sizeof(mark));
    45   d[dest] = p;
    46   mark[dest] = 1;
    47   for(int i = 0; i < n; i++) if(i != dest) {
    48     d[i] = INF;
    49     if(G[i][dest]) d[i] = back(dest);
    50   }
    51 
    52   // Dijkstra主过程,逆推
    53   while(!mark[src]) {
    54     // 找最小的d
    55     int minu = -1;
    56     for(int i = 0; i < n; i++) if(!mark[i]) {
    57       if(minu < 0 || d[i] < d[minu]) minu = i;
    58     }
    59     mark[minu] = 1;
    60     // 更新其他结点的d
    61     for(int i = 0; i < n; i++) if(!mark[i]) {
    62       if(G[i][minu]) d[i] = min(d[i], back(minu));
    63     }
    64   }
    65 
    66   // 输出
    67   printf("%lld
    ", d[src]);
    68   printf("%c", format_node(src));
    69   int u = src;
    70   LL item = d[src];
    71   while(u != dest) {
    72     int next;
    73     for(next = 0; next < n; next++) // 找到第一个可以走的结点
    74       if(G[u][next] && forward(item, next) >= d[next]) break;
    75     item = d[next];
    76     printf("-%c", format_node(next));
    77     u = next;
    78   }
    79   printf("
    ");
    80 }
    81 
    82 int main() {
    83   int kase = 0;
    84   while(scanf("%d", &n) == 1 && n >= 0) {
    85     memset(G, 0, sizeof(G));
    86     for(int i = 0; i < n; i++) {
    87       int u = read_node();
    88       int v = read_node();
    89       if(u != v) G[u][v] = G[v][u] = 1;
    90     }
    91     scanf("%d", &p);
    92     src = read_node();
    93     dest = read_node();
    94     printf("Case %d:
    ", ++kase);
    95     solve();
    96   }
    97   return 0;
    98 }
    LRJ

    Halum

     UVA - 11478 

    差分约束

    简直要崩溃了,,无法理解。。。。。。


    事实证明是书上写错了,不是非负,而是要求必须大于0.

    忧伤=_=||

     1 // UVa11478 Halum
     2 // Rujia Liu
     3 #include<cstdio>
     4 #include<cstring>
     5 #include<queue>
     6 using namespace std;
     7 
     8 const int INF = 1000000000;
     9 const int maxn = 500 + 10;
    10 const int maxm = 2700 + 10;
    11 
    12 struct Edge {
    13   int to, dist;
    14 };
    15 
    16 // 邻接表写法
    17 struct BellmanFord {
    18   int n, m;
    19   Edge edges[maxm];
    20   int head[maxn];
    21   int next[maxm];
    22   bool inq[maxn];   // 是否在队列中
    23   int d[maxn];      // s到各个点的距离
    24   int cnt[maxn];    // 进队次数
    25 
    26   void init(int n) {
    27     this->n = n;
    28     m = 0;
    29     memset(head, -1, sizeof(head));
    30   }
    31 
    32   void AddEdge(int from, int to, int dist) {
    33     next[m] = head[from];
    34     head[from] = m;
    35     edges[m++] = (Edge){to, dist};
    36   }
    37 
    38   bool negativeCycle() {
    39     queue<int> Q;
    40     memset(inq, 0, sizeof(inq));
    41     memset(cnt, 0, sizeof(cnt));
    42     for(int i = 0; i < n; i++) { d[i] = 0; Q.push(i); }
    43 
    44     int u;
    45     while(!Q.empty()) {
    46       u = Q.front(); Q.pop();
    47       inq[u] = false;
    48       for(int i = head[u]; i != -1; i = next[i]) {
    49         Edge& e = edges[i];
    50         if(d[e.to] > d[u] + e.dist) {
    51           d[e.to] = d[u] + e.dist;
    52           if(!inq[e.to]) { Q.push(e.to); inq[e.to] = true; if(++cnt[e.to] > n) return true; }
    53         }
    54       }
    55     }
    56     return false;
    57   }
    58 };
    59 
    60 BellmanFord solver;
    61 
    62 // 判断在初始差分约束系统的每个不等式右侧同时减去x之后是否有解
    63 bool test(int x) {
    64   for(int i = 0; i < solver.m; i++)
    65     solver.edges[i].dist -= x;
    66   bool ret = solver.negativeCycle();
    67   for(int i = 0; i < solver.m; i++)
    68     solver.edges[i].dist += x;
    69   return !ret; // 如果有负环,说明差分约束系统无解
    70 }
    71 
    72 int main() {
    73   int n, m;
    74   while(scanf("%d%d", &n, &m) == 2) {
    75     solver.init(n);
    76     int ub = 0;
    77     while(m--) {
    78       int u, v, d;
    79       scanf("%d%d%d", &u, &v, &d); ub = max(ub, d);
    80       solver.AddEdge(u-1, v-1, d);
    81     }
    82 
    83     if(test(ub+1)) printf("Infinite
    "); // 如果可以让每条边权都>ub,说明每条边的权都增加了,重复一次会增加得更多...直到无限
    84     else if(!test(1)) printf("No Solution
    ");
    85     else {
    86       int L = 2, R = ub, ans = 1;
    87       while(L <= R) {
    88         int M = L + (R-L)/2;
    89         if(test(M)) { ans = M; L = M+1; } else R = M-1;
    90       }
    91       printf("%d
    ", ans);
    92     }
    93   }
    94   return 0;
    95 }
    !!
  • 相关阅读:
    【HTML XHTML CSS基础教程(第6版)】笔记之CSS笔记(7~25章)
    【HTML XHTML CSS基础教程(第6版)】笔记之HTML XHTML笔记(1~6章)
    ASP.NET Ajax简单的无刷新分页
    ArrayList 、Vector 和 LinkedList 有什么区别?
    找工作的一些建议
    WorkSkill整理之 java用Scanner 类输入数组并打印
    PTE 准备之 Describe Image
    PTE 准备之 Repeat sentence
    WorkSkill 面试之 字节跳动一面
    与用户交互
  • 原文地址:https://www.cnblogs.com/yijiull/p/7209418.html
Copyright © 2011-2022 走看看