zoukankan      html  css  js  c++  java
  • Bzoj3258 秘密任务

    Time Limit: 10 Sec  Memory Limit: 128 MB
    Submit: 140  Solved: 59

    Description

    Alice听说在一片神奇的大陆MagicLand,有一个古老的传说…… 
     很久很久以前,那个时候 MagicStates共和国刚刚成立。 反对新政府的势力虽已被镇压,但仍然在暗地活动。这一次,情报局得到了一个令人震惊的消息,被软禁在首都府邸中的Frank ——著名的反对派领袖,秘密逃出首都,去往反对派的大本营。根据相关的情报,Frank计划通过城市之间 发达的高速公路,经过最短的路程抵达目的地。不妨将 MagicStates共和国简化为由N个城市,M条高速公路构成的连通的无向图,首都为城市1,反对派的大本营为城市N。 
    每条高速公路连接两个不同的城市,且路程是已知的。而Frank选择了一条从城市1到城市N的最短路径作为他的逃跑路线。为了阻止Frank,共和国总统决定在某些城市的高速公路的出入口设立检查 点,在Frank经过检查点时将他逮捕。 
    举例来说,如果有一条高速公路连接城市u和城市v,在这条公路的城市u或城市v的出入口设立检查点,那么Frank经过高速公路时就会被发现。特别的是,由于城市N实际上处在反对派的控制下,所以不能在城市N设立检查点。

    然而在任何城市设立检查点都需要一定的费用。更具体的,若在城市 u设立k个检查点,就要花费 Au乘以k的代价,其中Au是城市u的相关参数。值得注意的是,这个代价与这k个检查点具体设在哪些公路的出入口无关,于是,总统责令情报局拟定一个方案,花费最小的代价使得无论Frank选择哪条最短路线,都会在(除城市N以外)某个城市的高速公路出入口被发现。读到这里,Alice很想知道阻止Frank所需要花费的最小代价,并且她还希 望知道最优方案是否是唯一的。只好再请你帮助她了。 
    注意,我们称两个方案不同当且仅当存在某城市k,两种方案中在城市 k的检查点的设置(而不仅是数目)是不同的。 
    注意,输入文件包含多组测试数据。

    Input

    第一行包含一个正整数T,表示有T组测试数据。接下来依次是T组测试数据。 
     每组测试数据的第一行包含两个整数 N、M。 
    第二行包含N - 1个正整数,依次表示A1,A2, …,An-1。
    接下来M行,每行三个整数Ui,Vi,Ci,表示一条连接城市Ui和城市Vi的路程等于Ci的高速公路

    Output

    输出T行,依次表示每组测试数据的答案。若最优方案唯一则输出 ”Yes” 和
    最小代价,否则输出”No”和最小代价。字符串和整数之间请用一个空格隔开。

    Sample Input

    3
    3 3
    2 4
    1 3 23
    3 2 12
    2 1 11
    4 4
    3 2 2
    1 2 1
    2 3 1
    3 4 1
    4 1 1
    3 4
    3 2
    1 2 1
    2 3 2
    2 3 19
    3 1 4

    图论 网络流 最小割唯一性判定

    找出最短路,建立流量网络,跑最大流,在残量网络上跑tarjan。

    遍历每条割边,如果一条割边的两端点不在同一个强连通分量内且不是由S所在强连通分量指向T所在强连通分量,那么说明有多解。

    坑点:如果一条割边的两端点的代价相等,也算有多解。

      1 /*by SilverN*/
      2 #include<algorithm>
      3 #include<iostream>
      4 #include<cstring>
      5 #include<cstdio>
      6 #include<cmath>
      7 #include<vector>
      8 #include<queue>
      9 #define LL long long
     10 using namespace std;
     11 const LL INF=0x3f3f3f3f3f3f3f;
     12 const int mxn=300100;
     13 int read(){
     14     int x=0,f=1;char ch=getchar();
     15     while(ch<'0' || ch>'9'){if(ch=='-')f=-1;ch=getchar();}
     16     while(ch>='0' && ch<='9'){x=x*10+ch-'0';ch=getchar();}
     17     return x*f;
     18 }
     19 int n,m,S,T;
     20 struct edge{
     21     int u,v,nxt;
     22     LL f;
     23 }e[mxn<<2],eg[mxn<<2];
     24 int hd[mxn],hd2[mxn],mct1=0,mct=1;
     25 void add(int u,int v,LL d){
     26     eg[++mct1].nxt=hd2[u];
     27     eg[mct1].u=u;eg[mct1].v=v;
     28     eg[mct1].f=d;
     29     hd2[u]=mct1;
     30     return;
     31 }
     32 void add_edge(int u,int v,LL w){
     33     e[++mct].nxt=hd[u];e[mct].u=u;e[mct].v=v;e[mct].f=w;hd[u]=mct;return;
     34 }
     35 void insert(int u,int v,LL w){
     36     add_edge(u,v,w);
     37     add_edge(v,u,0);
     38 }
     39 int d[mxn];
     40 bool BFS(){
     41     memset(d,0,sizeof d);
     42     queue<int>q;
     43     q.push(S);d[S]=1;
     44     while(!q.empty()){
     45         int u=q.front();q.pop();
     46         for(int i=hd[u];i;i=e[i].nxt){
     47             int v=e[i].v;
     48             if(!e[i].f || d[v])continue;
     49             d[v]=d[u]+1;
     50             q.push(v);
     51         }
     52     }
     53     return d[T];
     54 }
     55 LL DFS(int u,LL lim){
     56     if(u==T)return lim;
     57     LL f=0,tmp;
     58     for(int i=hd[u];i;i=e[i].nxt){
     59         int v=e[i].v;
     60         if(d[v]==d[u]+1 && e[i].f && (tmp=DFS(e[i].v,min(lim,e[i].f)))){
     61             e[i].f-=tmp;
     62             e[i^1].f+=tmp;
     63             f+=tmp;
     64             lim-=tmp;
     65             if(!lim)return f;
     66         }
     67     }
     68     d[u]=0;
     69     return f;
     70 }
     71 LL Dinic(){
     72     LL res=0;
     73     while(BFS())res+=DFS(S,INF);
     74     return res;
     75 }
     76 //
     77 int dfn[mxn],low[mxn],dtime=0;
     78 int belong[mxn],scc=0;
     79 int st[mxn],top=0;
     80 bool inst[mxn];
     81 void tarjan(int u){
     82     dfn[u]=low[u]=++dtime;
     83     st[++top]=u;
     84     inst[u]=1;
     85     for(int i=hd[u];i;i=e[i].nxt){
     86         int v=e[i].v;if(!e[i].f)continue;
     87         if(!dfn[v]){
     88             tarjan(v);
     89             low[u]=min(low[u],low[v]);
     90         }
     91         else if(inst[v]){
     92             low[u]=min(low[u],dfn[v]);
     93         }
     94     }
     95     if(low[u]==dfn[u]){
     96         int v=0;
     97         ++scc;
     98         do{
     99             v=st[top--];
    100             inst[v]=0;
    101             belong[v]=scc;
    102         }while(u!=v);
    103     }
    104     return;
    105 }
    106 //
    107 LL dis[4050];//,dis2[405];
    108 struct dist{
    109     int v;
    110     LL dis;
    111     bool operator < (dist b)const{return dis>b.dis;}
    112 };
    113 priority_queue<dist>q;
    114 void Dij(int s){
    115 //    printf("in
    ");
    116     memset(dis,0x3f,sizeof dis);
    117     dis[s]=0;
    118     q.push((dist){s,0});
    119     while(!q.empty()){
    120         dist tmp=q.top();q.pop();
    121         if(tmp.dis>dis[tmp.v]){continue;}
    122         int u=tmp.v;
    123         for(int i=hd2[u],v;i;i=eg[i].nxt){
    124             v=eg[i].v;
    125             if(dis[v]>dis[u]+eg[i].f){
    126                 dis[v]=dis[u]+eg[i].f;
    127                 q.push((dist){v,dis[v]});
    128             }
    129         }
    130     }
    131     return;
    132 }
    133 int cnt=0;
    134 LL au[mxn];
    135 LL ans;
    136 void Build(){
    137     Dij(1);
    138     for(int i=1;i<=mct1;i++){
    139         if(dis[eg[i].u]+eg[i].f==dis[eg[i].v]){
    140             cnt++;
    141             insert(eg[i].u,eg[i].v,min(au[eg[i].u],au[eg[i].v]));
    142         }
    143     }
    144     S=1;T=n;
    145     ans=Dinic();
    146     return;
    147 }
    148 void solve(){
    149     int i,j;
    150     for(i=1;i<=n;i++)
    151         if(!dfn[i])tarjan(i);
    152     bool flag=1;
    153     for(i=2;i<=mct;i+=2){
    154         if(e[i].f==0){
    155             int u=e[i].u,v=e[i].v;
    156             if(belong[u]==belong[v])continue;
    157 //            printf("u:%d v:%d bu:%d bv:%d
    ",u,v,belong[u],belong[v]);
    158             if( (belong[u]!=belong[S] || belong[v]!=belong[T]) 
    159                 && (belong[u]!=belong[T] || belong[v]!=belong[S])){
    160                 flag=0;break;
    161             }
    162             if(au[u]==au[v]){
    163                 flag=0;break;
    164             }
    165         }
    166     }
    167     if(flag)printf("Yes ");
    168     else printf("No ");
    169     printf("%lld
    ",ans);
    170     return;
    171 }
    172 //
    173 //
    174 void init(){
    175     memset(hd,0,sizeof hd);
    176     memset(hd2,0,sizeof hd2);
    177     memset(dfn,0,sizeof dfn);
    178     memset(low,0,sizeof low);
    179     mct1=0;mct=1;
    180     cnt=0;scc=0;dtime=0;
    181     //
    182     return;
    183 }
    184 int main(){
    185     freopen("in.txt","r",stdin);
    186     int i,j;
    187     int T=read();
    188     while(T--){
    189         init();
    190         n=read();m=read();
    191         for(i=1;i<n;i++)au[i]=read();
    192         au[n]=INF;
    193         int u,v,w;
    194         for(i=1;i<=m;i++){
    195             u=read();v=read();w=read();
    196 //            printf("%d to %d :%d
    ",u , v, w );
    197             add(u,v,w);
    198             add(v,u,w);
    199         }
    200         Build();
    201         solve();
    202     }
    203     return 0;
    204 }
  • 相关阅读:
    2019-11-12-WPF-添加窗口消息钩子方法
    2018-11-21-WPF-解决-ViewBox--不显示线的问题
    ARRAY_SIZE宏
    tcp校验和
    arp命令
    sk_buff
    printf打印字节
    dmesg命令
    insmod/rmmod
    ifup/ifdown
  • 原文地址:https://www.cnblogs.com/SilverNebula/p/6706306.html
Copyright © 2011-2022 走看看