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
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 }