传智杯省赛 小苯的网络配置(A组、B组、C组)

时间限制:C/C++/Rust/Pascal 2秒,其他语言4秒
空间限制:C/C++/Rust/Pascal 256 M,其他语言512 M
64bit IO Format: %lld

题目描述 

小苯正在配置机房的网络环境。
具体来说,机房有 nn 台主机(电脑),和 mm 条网线,每条网线都有严格的连接规定,具体的:第 ii 条网线必须连接 uiui​ 和 vivi​ 这两台主机,连接后使用该网线传输数据的花费为 wiwi​。
 

熟练电脑的小苯很快就配好了所有的线路,此时无聊的小苯突然对这个网络的最小传输花费产生了兴趣,他想知道从 11 号主机传输数据到 nn 号主机的最小花费。但很快他就求出了这个答案,因此他认为这个问题太简单了,他现在提出了一个更难的问题:

对于 11 到 mm 的每一条网线,是否存在某个从 11 号主机到 nn 号主机的最小花费传输路径一定经过了这条网线。

他被自己提出的新问题难住了,请你帮帮他吧。

输入描述:

 
  

每个测试文件均包含多组测试数据。第一行输入一个整数 T(1≤T≤104)T(1≤T≤104) 代表数据组数,每组测试数据描述如下:

在第一行输入两个正整数 n,m (1≤n≤105,1≤m≤2×105)n,m (1≤n≤105,1≤m≤2×105),分别表示机房中的主机个数 nn 和网线条数 mm。

在紧接着的 mm 行中,每行三个正整数 ui,vi,wi (1≤ui,vi≤n,1≤wi≤109)ui​,vi​,wi​ (1≤ui​,vi​≤n,1≤wi​≤109),分别表示每条网线连接的两个主机的编号,以及在此网线传输数据消耗的代价。

(保证同一个测试文件中,nn 的总和不超过 105105,mm 的总和不超过 2×1052×105。)

输出描述:

对于每组测试数据,在单独的一行上输出一个长度为 mm 的 0101 串 ss。(如果第 ii 条网线一定处于某个从 11 号主机到 nn 号主机的最小花费传输路径上,则 si=si​= "1",否则 si=si​= "0")。

示例1

输入

复制

2
4 6
1 2 1
1 3 2
1 4 3
2 3 2
2 4 2
3 4 2
3 2
1 2 3
1 2 1

输出

复制

101010
00

说明

 
  

对于第一组测试数据:

如图,圈成红色的网线都是符合要求的网线,即:从一定存在某个从 11 号主机传输到 44 号主机的最短花费传输路径经过此网线。

第二组测试数据中,由于 11 号和 33 号主机之间无法传输数据,因此所有的网线都不符合要求。  

解题思路:这道题的题意是判断一条v)在最短路径上,那如何判断它是否是在最短路径上呢,如果起点到u的距离加上这条边的的距离再加上终点n到v的距离等于等于1到n的最短距离dis[n]就可以判断它在最短路径上,由于这是一条无向边所还要判断起点到v的最短距离加上这条边的的最短距离再加上终点n到u的最短距离等于1到n的最短距离dis[n]就可以判断它在最短路径上;两者只要满足一个,那它就在最短路径上;

  if((d1[n]==(d1[u]+w+dn[v]))||(d1[n]==(d1[v]+w+dn[u]))){
                cout<<1;
                 
            }else{
                cout<<0;
               

那么起点1到u,v的最短距离就需要对点1用最短路算法求d1[u],d1[v];终点n到u,v的最短距离就需要对点n用最短路算法求d1[u],d1[v];

d1[1]=0;
        dijkstra(1,d1);
         dn[n]=0;
         dijkstra(n,dn);
        

AC代码
 

#include
#include
#include
#include
using namespace std;
#define int long long
#define PII pair
#define IOS ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
const int N=1e6+10;
int d1[N],dn[N],cnt,head[N];
struct node{
    int to;
    int w;
    int next;
    int u;
}edge[N];
void dijkstra(int s,int d[]){
    priority_queue,greater >q;
    int u;
    q.push({0,s});
    while(q.size()){
//    	cout<<"????"< d[u]) continue;//这里一定要有,不然会超时 
        for(int i=head[u];i!=-1;i=edge[i].next){
//        	cout<d[u]+edge[i].w){
                d[v]=d[u]+edge[i].w;
                q.push({d[v],v});
            }
        }
    }
    
}
void add(int u,int v,int w){
    edge[cnt].to=v;
    edge[cnt].w=w;
    edge[cnt].next=head[u];
    edge[cnt].u=u;
   
    head[u]=cnt++;
     
}
signed main(){
      ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
 int n,m,w,v,u,k;
     
     
   
    cin>>k;
    while(k--){
    	memset(head,-1,sizeof(head));
    memset(d1,0x3f3f3f3f,sizeof(d1));
    memset(dn,0x3f3f3f3f,sizeof(dn));
    	cnt=0;
        
        cin>>n>>m;
        for(int i=0;i>u>>v>>w;
            add(u,v,w);
            add(v,u,w);
        }
       
         
        d1[1]=0;
        dijkstra(1,d1);
         dn[n]=0;
         dijkstra(n,dn);
        
          
        for(int i=0;i

你可能感兴趣的:(网络,c语言,开发语言)