2017 新疆赛区网络赛 J Our Journey of Dalian Ends 费用流

题目描述:

Life is a journey, and the road we travel has twists and turns, which sometimes lead us to unexpected places and unexpected people.

Now our journey of Dalian ends. To be carefully considered are the following questions.

Next month in Xian, an essential lesson which we must be present had been scheduled.

But before the lesson, we need to attend a wedding in Shanghai.

We are not willing to pass through a city twice.

All available expressways between cities are known.

What we require is the shortest path, from Dalian to Xian, passing through Shanghai.

Here we go.

Input Format

There are several test cases.

The first line of input contains an integer tt which is the total number of test cases.

For each test case, the first line contains an integer m~(m\le 10000)m (m≤10000) which is the number of known expressways.

Each of the following mm lines describes an expressway which contains two string indicating the names of two cities and an integer indicating the length of the expressway.

The expressway connects two given cities and it is bidirectional.

Output Format

For eact test case, output the shortest path from Dalian to Xian, passing through Shanghai, or output -1?1 if it does not exist.

题意抽象一下即为要求从A经过B到达C的最短路,并且要求路径上的点不可重复经过。

拆点后点内限流,建立源点S指向B容量为2的一条边,A,C分别建立一条指向汇点T容量为1的边。然后依题意建图即可。

跑一遍费用流便得到答案。

  1 #include<bits/stdc++.h>
  2 #define rep(i,a,b) for(int i=a;i<=b;i++)
  3 using namespace std;
  4 const int MAXN=101000;
  5 const int maxn=20000;
  6 const int INF=~0U>>1;
  7 int maxflow=0,cost=0;
  8 int pre[maxn],vis[maxn],dis[maxn];
  9 int S,T,S1;
 10 int n,m;
 11 int tot=0;
 12 int pointer[maxn];
 13 map<string,int> mp;
 14 int shanghai;
 15 struct Edge
 16 {
 17     int to,next,cap,f,w;
 18     Edge() {};
 19     Edge(int b,int c,int nxt,int flow,int weight) {to=b,cap=c,next=nxt,f=flow,w=weight;}
 20 }edge[MAXN];
 21 inline void addedge(int a,int b,int c,int w1)
 22 {
 23     edge[tot]=Edge(b,c,pointer[a],0,w1);
 24     pointer[a]=tot++;
 25     edge[tot]=Edge(a,0,pointer[b],0,-w1);
 26     pointer[b]=tot++;
 27 }
 28 bool spfa(int s,int t)
 29 {
 30     queue<int > q;
 31     rep(i,S,T)
 32     {
 33         dis[i]=INF;
 34         vis[i]=false;
 35         pre[i]=-1;
 36     }
 37     dis[S]=0;
 38     vis[S]=1;
 39     q.push(S);
 40     while(!q.empty())
 41     {
 42         int u=q.front();q.pop();
 43         vis[u]=0;
 44         for(int j=pointer[u];j!=-1;j=edge[j].next)
 45         {
 46             int v=edge[j].to;
 47       //      if(u==92) printf("u=92 v=%d\n",v);
 48             if(edge[j].cap-edge[j].f>0&&dis[v]>dis[u]+edge[j].w)
 49             {
 50                 dis[v]=dis[u]+edge[j].w;
 51                 pre[v]=j;
 52                 if(!vis[v])
 53                 {
 54                     vis[v]=1;q.push(v);
 55                 }
 56             }
 57         }
 58     }
 59     if(pre[T]==-1) return false;
 60     else return true;
 61 }
 62 int mcmf()
 63 {
 64     int flow=0;
 65     cost=0;
 66     while(spfa(S,T))
 67     {
 68         int mi=INF;
 69         for(int i=pre[T];i!=-1;i=pre[edge[i^1].to])
 70         {
 71             mi=min(mi,edge[i].cap-edge[i].f);
 72         }
 73         for(int i=pre[T];i!=-1;i=pre[edge[i^1].to])
 74         {
 75             edge[i].f+=mi;
 76             edge[i^1].f-=mi;
 77            // printf("edge[%d].w=%d edge[i].to=%d\n",i,edge[i].w,edge[i].to);
 78             //cost+=edge[i].w*mi;
 79         }
 80        // flow+=mi;
 81     }
 82     return flow;
 83 }
 84 void Input()
 85 {
 86     mp.clear();
 87     scanf("%d",&m);
 88     string a;
 89     string b;
 90     int len;
 91     int cnt=1;
 92     memset(pointer,-1,sizeof(pointer));
 93     tot=0;
 94     rep(i,1,m)
 95     {
 96         cin>>a>>b>>len;
 97         if(mp[a]==0)
 98         {
 99             mp[a]=cnt;
100             addedge(cnt,cnt+1,1,0);
101            // if(a=="Shanghai") shanghai=cnt;
102             cnt+=2;
103
104         }
105         if(mp[b]==0)
106         {
107             mp[b]=cnt;
108             addedge(cnt,cnt+1,1,0);
109          //   if(b=="Shanghai") shanghai=cnt;
110             cnt+=2;
111         }
112         addedge(mp[a]+1,mp[b],INF,len);
113       //  addedge(mp[b],mp[a]+1,1,len);
114         addedge(mp[b]+1,mp[a],INF,len);
115         //addedge(mp[a],mp[b]+1,1,len);
116     }
117     S=0;T=cnt;
118    // printf("shanghai=%d\n",mp["Shanghai"]);
119     addedge(mp["Shanghai"],mp["Shanghai"]+1,1,0);
120     addedge(S,mp["Shanghai"],2,0);
121     addedge(mp["Xian"]+1,T,1,0);
122     addedge(mp["Dalian"]+1,T,1,0);
123 }
124 int main()
125 {
126    // freopen("in.txt","r",stdin);
127     int T;
128     scanf("%d",&T);
129     rep(t1,1,T)
130     {
131         Input();
132         maxflow=mcmf();
133         if(maxflow==2) printf("%d\n",cost);
134         else printf("-1\n");
135     }
136     return 0;
137 }
时间: 2024-08-29 06:41:17

2017 新疆赛区网络赛 J Our Journey of Dalian Ends 费用流的相关文章

HDU5006 Resistance (2014年鞍山赛区网络赛J题)

1.题目描述:点击打开链接 2.解题思路:本题利用缩点+高斯消元解决.本题的最大特点就是电阻非零即一,如果电阻为0,说明零点之间是等电位点,可以看做一个整体,自然可以想到先利用并查集进行缩点操作,将复杂的电路图转化为不相等的电位点构成的电路图.如果转换完毕后,发现s和t在一个集合中,说明两点之间是等电位的,等效电阻为0,否则,对转换后的图G'重新判断连通性,依然可以利用并查集解决,如果发现不连通,说明s与t之间开路,电阻为inf,否则,就可以根据tot个点的电位列写方程. 我们令有1A的电流从点

hdu 4049 2011北京赛区网络赛J 状压dp ***

cl少用在for循环里 1 #include<cstdio> 2 #include<iostream> 3 #include<algorithm> 4 #include<cstring> 5 #include<cmath> 6 #include<queue> 7 #include<map> 8 using namespace std; 9 #define MOD 1000000007 10 const int INF=0x

ZOJ 3818 Pretty Poem (2014年牡丹江赛区网络赛J题)

1.题目描述:点击打开链接 2.解题思路:本题是一道模拟题,输入一个串,要求判断是否形如"ABABA"或"ABABCAB".只需要对两种情况逐一尝试即可.然而这道题有诸多细节需要考虑.这里说一下我自己的方法. 首先,如果输入的串长度<5,那么直接输出No,或者去掉所有的标点后发现长度<5,输出No.长度上没问题后,写一个专门的solve(int type)函数,来判断是否是上述情况中的一种.对于第一种,只需要枚举A的长度即可,B的长度就是(len-3*i

hdu 4070 福州赛区网络赛J 贪心 ***

优先发路程最长的 1 #include<cstdio> 2 #include<iostream> 3 #include<algorithm> 4 #include<cstring> 5 #include<cmath> 6 #include<queue> 7 #include<map> 8 using namespace std; 9 #define MOD 1000000007 10 const int INF=0x3f3

ICPC 2018 徐州赛区网络赛

ACM-ICPC 2018 徐州赛区网络赛 ?去年博客记录过这场比赛经历:该死的水题 ?一年过去了,不被水题卡了,但难题也没多做几道.水平微微有点长进. ? ? D. Easy Math 题意: ? 给定 \(n\), \(m\) ,求 \(\sum _{i=1}^{m} \mu(in)\) .其中 $ 1 \le n \le 1e12$ , $ 1 \le m \le 2e9$ ,\(\mu(n)\) 为莫比乌斯函数. ? 思路: ? 容易知道,\(i\) 与 \(n\) 不互质时, \(\m

西电校赛网络赛J题 lucas定理计算组合数

西电校赛网络赛J题  lucas定理计算组合数 问题 J: 找规律II 时间限制: 1 Sec  内存限制: 128 MB 提交: 96  解决: 16 [提交][状态][讨论版] 题目描述 现有数阵如下: 1    2  3   4     5    6 1   3   6  10  15 1   4  10   20 1   5   15 1    6 1 求这个数阵的第n行m列是多少(行列标号从1开始) 结果对10007取模 输入 多组数据,每组数据一行,包含两个整数n,m(1<=n<=

ACM-ICPC 2018 徐州赛区网络预赛 J. Maze Designer (最大生成树+LCA求节点距离)

ACM-ICPC 2018 徐州赛区网络预赛 J. Maze Designer J. Maze Designer After the long vacation, the maze designer master has to do his job. A tour company gives him a map which is a rectangle. The map consists of N \times MN×M little squares. That is to say, the h

HDU 5875 Function -2016 ICPC 大连赛区网络赛

题目链接 网络赛的水实在太深,这场居然没出线zzz,差了一点点,看到这道题的的时候就剩半个小时了.上面是官方的题意题解,打完了才知道暴力就可以过,暴力我们当时是想出来了的,如果稍稍再优化一下估计就过了zzz.去年有一场现场赛也是n=1000,n^3过了,看来关键时刻实在做不出来就得大胆暴力啊. #include <bits/stdc++.h> using namespace std; typedef long long ll; const int maxn=1e5+5; int a[maxn]

hihocoder1236(北京网络赛J):scores 分块+bitset

北京网络赛的题- -.当时没思路,听大神们说是分块+bitset,想了一下发现确实可做,就试了一下,T了好多次终于过了 题意: 初始有n个人,每个人有五种能力值,现在有q个查询,每次查询给五个数代表查询的五种能力值,输出有多少个人每种能力值都比查询的小 n和q都是50000,每种能力值最大也为50000 思路: 对于某一个大小的能力值,有哪些人的此项能力值比他小可以用一个50000的bitset表示.这样我们在查询的时候就可以拿到5个对应的bitset,对其进行and就可以得出最终的人数 这样每