1. poj 1502 Mathches Game

  裸最短路

 #include <iostream>
#include <string.h>
#include <cstdio>
#include <queue>
#include <vector>
#include <string>
#include <cstring>
#include <algorithm>
#include <math.h> #define SIGMA_SIZE 26
#pragma warning ( disable : 4996 ) using namespace std;
typedef long long LL; inline LL LMax(LL a,LL b) { return a>b?a:b; }
inline LL LMin(LL a,LL b) { return a>b?b:a; }
inline int Max(int a,int b) { return a>b?a:b; }
inline int Min(int a,int b) { return a>b?b:a; }
inline int gcd( int a, int b ) { return b==?a:gcd(b,a%b); }
inline int lcm( int a, int b ) { return a/gcd(a,b)*b; } //a*b = gcd*lcm
const long long INF = 0x3f3f3f3f3f3f3f3f;
const int inf = 0x3f3f3f3f;
const int mod = ;
const int maxk = ;
const int maxn = ; struct edge {
int to, next, val;
}e[maxn*maxn]; int dis[maxn], linjie[maxn];
bool vis[maxn];
int N, cnt, ans; void addedge( int x, int y, int val )
{
e[cnt].to = y; e[cnt].next = linjie[x]; e[cnt].val = val; linjie[x] = cnt++; } void init()
{
cnt = ans = ;
memset( linjie, -, sizeof(linjie) );
memset( dis, 0x3f, sizeof(dis) );
memset( vis, , sizeof(vis) );
} void read()
{
init();
string str;
int tmp = ; for ( int i = ; i < N; i++ )
{
for ( int j = ; j < tmp; j++ )
{
int val = ;
cin >> str; if ( str == "x" )
continue;
int len = str.length(); int x = ;
for ( int k = len - ; k >= ; k-- )
{
val += (str[k]-'')*x;
x *= ;
}
addedge( i, j, val );
addedge( j, i, val );
}
tmp++;
}
} void dijkstra()
{
dis[] = ; for ( int i = ; i < N; i++ )
{
int mindis = inf, mark = -;
for ( int j = ; j < N; j++ )
if ( !vis[j] && dis[j] < mindis )
{
mark = j;
mindis = dis[j];
} vis[mark] = true; for ( int j = linjie[mark]; j+; j = e[j].next )
if (!vis[e[j].to])
{
int v = e[j].to, val = e[j].val;
dis[v] = Min(dis[v], dis[mark]+val);
}
}
} int main()
{
cin >> N; read();
dijkstra(); for ( int i = ; i < N; i++ )
ans = Max( ans, dis[i] ); cout << ans << endl;
return ;
}

2. poj 3660 cow contest

  floyd 求传递闭包

 #include <iostream>
#include <string.h>
#include <cstdio>
#include <queue>
#include <vector>
#include <string>
#include <cstring>
#include <algorithm>
#include <math.h> #define SIGMA_SIZE 26
#pragma warning ( disable : 4996 ) using namespace std;
typedef long long LL; inline LL LMax(LL a,LL b) { return a>b?a:b; }
inline LL LMin(LL a,LL b) { return a>b?b:a; }
inline int Max(int a,int b) { return a>b?a:b; }
inline int Min(int a,int b) { return a>b?b:a; }
inline int gcd( int a, int b ) { return b==?a:gcd(b,a%b); }
inline int lcm( int a, int b ) { return a/gcd(a,b)*b; } //a*b = gcd*lcm
const long long INF = 0x3f3f3f3f3f3f3f3f;
const int inf = 0x3f3f3f3f;
const int mod = ;
const int maxk = ;
const int maxn = ; bool mmap[maxn][maxn];
int ojbk[maxn];
int N, M; void floyd()
{
for ( int k = ; k <= N; k++ )
for ( int i = ; i <= N; i++ )
for ( int j = ; j <= N; j++ )
{
mmap[i][j] = (mmap[i][j] || (mmap[i][k] && mmap[k][j]));
}
} int main()
{
cin >> N >> M; int x, y;
for ( int i = ; i <= M; i++ )
{
scanf("%d %d", &x, &y);
mmap[x][y] = ;
} floyd(); int ans = ;
for ( int i = ; i <= N; i++ )
for ( int j = ; j <= N; j++ )
if ( mmap[i][j] )
{
ojbk[i]++;
ojbk[j]++;
} for ( int i = ; i <= N; i++ )
if ( ojbk[i] == N- )
ans++;
cout << ans << endl; return ;
}

3. poj 1511 Invitation Cards

  双向最短路,正着求一次,边取反再求一次

 #include <iostream>
#include <string.h>
#include <cstdio>
#include <queue>
#include <map>
#include <vector>
#include <string>
#include <cstring>
#include <algorithm>
#include <math.h> #define SIGMA_SIZE 26
#pragma warning ( disable : 4996 ) using namespace std;
typedef long long LL; inline LL LMax(LL a,LL b) { return a>b?a:b; }
inline LL LMin(LL a,LL b) { return a>b?b:a; }
inline int Max(int a,int b) { return a>b?a:b; }
inline int Min(int a,int b) { return a>b?b:a; }
inline int gcd( int a, int b ) { return b==?a:gcd(b,a%b); }
inline int lcm( int a, int b ) { return a/gcd(a,b)*b; } //a*b = gcd*lcm
const long long INF = 0x3f3f3f3f3f3f3f3f;
const int inf = 0x3f3f3f3f;
const int mod = ;
const int maxk = ;
const int maxn = 1e6+; int num[*maxn];
int linjie[maxn];
int dis[maxn];
bool vis[maxn];
int P, Q, cnt;
long long ans; struct edge {
int to, next, val ;
}e[maxn]; struct cmp {
bool operator() ( const int a, const int b )
{ return dis[a]>dis[b]; }
}; void addedge( int u, int v, int val )
{ e[cnt].to = v; e[cnt].next = linjie[u]; e[cnt].val = val; linjie[u] = cnt++; } void init()
{
cnt = ; ans = ;
memset( linjie, -, sizeof(linjie) );
} void dijkstra()
{
memset( dis, 0x3f, sizeof(dis) );
memset( vis, , sizeof(vis) ); priority_queue<int, vector<int>, cmp> q;
dis[] = ;
q.push(); while (!q.empty())
{
int run = q.top(); q.pop();
int mindis = dis[run]; vis[run] = true; for ( int i = linjie[run]; i+; i = e[i].next )
if ( !vis[e[i].to] && dis[e[i].to] > mindis + e[i].val )
{
dis[e[i].to] = mindis + e[i].val;
q.push(e[i].to);
}
}
for ( int i = ; i <= P; i++ )
ans += (long long)dis[i];
} int main()
{
int n;
cin >> n; while (n--)
{
init();
scanf( "%d %d", &P, &Q ); int j = ;
for ( int i = ; i <= Q; i++ )
{
scanf( "%d %d %d", &num[j], &num[j+], &num[j+] );
addedge( num[j], num[j+], num[j+] );
j += ;
}
dijkstra(); //重新建边///
memset( linjie, -, sizeof(linjie) );
cnt = ; j = ;
for ( int i = ; i <= Q; i++ )
{
addedge( num[j+], num[j], num[j+] );
j += ;
} dijkstra(); printf( "%lld\n", ans );
} return ;
}

4.poj 3159 Candies

  dijsktra+优先队列优化+差分约束

 #include <iostream>
#include <string.h>
#include <stdio.h>
#include <algorithm>
#include <queue>
#include <vector>
#define SIGMA_SIZE 26
#pragma warning ( disable : 4996 ) using namespace std;
typedef long long LL; inline LL LMax(LL a,LL b) { return a>b?a:b; }
inline LL LMin(LL a,LL b) { return a>b?b:a; }
inline int Max(int a,int b) { return a>b?a:b; }
inline int Min(int a,int b) { return a>b?b:a; }
inline int gcd( int a, int b ) { return b==?a:gcd(b,a%b); }
inline int lcm( int a, int b ) { return a/gcd(a,b)*b; } //a*b = gcd*lcm
const long long INF = 0x3f3f3f3f3f3f3f3f;
const int inf = 0x3f3f3f3f;
const int mod = ;
const int maxk = + ;
const int maxn = + ; int linjie[maxn];
int dis[maxn];
bool vis[maxn];
int P, Q, cnt; struct qnode
{
int v;
int c;
qnode(int _v=,int _c=):v(_v),c(_c){}
bool operator <(const qnode &r)const
{
return c>r.c;
}
}; struct edge {
int to, next, val ;
}e[maxk]; void addedge( int u, int v, int val )
{ e[cnt].to = v; e[cnt].next = linjie[u]; e[cnt].val = val; linjie[u] = cnt++; } void init()
{
cnt = ;
memset( linjie, -, sizeof(linjie) );
} void dijkstra()
{
memset( dis, 0x3f, sizeof(dis) );
memset( vis, , sizeof(vis) ); priority_queue<qnode> q;
while(!q.empty()) q.pop();
dis[] = ;
q.push(qnode(,)); qnode tmp; while (!q.empty())
{
tmp = q.top(); q.pop();
int run = tmp.v;
int mindis = dis[run]; vis[run] = true; for ( int i = linjie[run]; i+; i = e[i].next )
if ( !vis[e[i].to] && dis[e[i].to] > mindis + e[i].val )
{
int v = e[i].to;
dis[v] = mindis + e[i].val;
q.push(qnode(v, dis[v]));
}
}
} int main()
{
init();
scanf( "%d%d", &P, &Q ); int x, y, z;
for ( int i = ; i <= Q; i++ )
{
scanf( "%d%d%d", &x, &y, &z );
addedge(x,y,z);
} dijkstra(); printf( "%d\n", dis[P] ); return ;
}

5. poj 3169 Layout

  spfa+负环+差分约束

  最经典的差分约束,因为求的是dis[N]-dis[1]的最大值 ,即dis[N]-dis[1] <= x,所以用最短路。用spfa判断若有负环,说明最短路无限小,所以无解;若dis[N] = inf,说明最短路可以无限大,

 #include <iostream>
#include <string.h>
#include <cstdio>
#include <queue>
#include <map>
#include <vector>
#include <string>
#include <cstring>
#include <algorithm>
#include <math.h> #define SIGMA_SIZE 26
#pragma warning ( disable : 4996 ) using namespace std;
typedef long long LL; inline LL LMax(LL a,LL b) { return a>b?a:b; }
inline LL LMin(LL a,LL b) { return a>b?b:a; }
inline int Max(int a,int b) { return a>b?a:b; }
inline int Min(int a,int b) { return a>b?b:a; }
inline int gcd( int a, int b ) { return b==?a:gcd(b,a%b); }
inline int lcm( int a, int b ) { return a/gcd(a,b)*b; } //a*b = gcd*lcm
const long long INF = 0x3f3f3f3f3f3f3f3f;
const int inf = 0x3f3f3f3f;
const int mod = ;
const int maxk = 2e4+;
const int maxn = ; int N, Ml, Md, cnt;
int linjie[maxn], in[maxn];
bool vis[maxn];
long long dis[maxn]; struct edge {
int to, next, val;
}e[maxk]; void addedge( int u, int v, int val )
{
e[cnt].to = v;
e[cnt].next = linjie[u];
e[cnt].val = val;
linjie[u] = cnt++;
} void init()
{
cnt = ;
memset( linjie, -, sizeof(linjie) );
} long long spfa()
{
memset( dis, 0x3f, sizeof(dis) ); queue<int> q;
q.push(); dis[] = ; while ( !q.empty() )
{
int run = q.front(); q.pop();
vis[run] = false; for ( int i = linjie[run]; i+; i = e[i].next )
{
int v = e[i].to, cost = e[i].val;
if ( dis[v] > dis[run] + cost )
{
dis[v] = dis[run] + cost;
if (!vis[v])
{
in[v]++;
if ( in[v] > N ) return -; vis[v] = true;
q.push(v);
}
}
}
} if ( dis[N] == INF ) return -;
else
return dis[N];
} int main()
{
init();
cin >> N >> Ml >> Md; //差分约束条件建边
int a, b, z;
for ( int i = ; i <= Ml; i++ )
{ scanf("%d%d%d", &a, &b, &z); addedge(a,b,z); }
for ( int i = ; i <= Md; i++ )
{ scanf("%d%d%d", &a, &b, &z); addedge(b,a,-z); } printf( "%lld\n", spfa() );
return ;
}

6. hdu3416 Marriage Match IV

  dijkstra+最大流dinic当前弧优化

  hdu的题好难...这题最不一样的是求一共有多少条最短路(路径不可以重复),一个暴力的想法就是求一条最短路再删去该路的所有边,再求最短路,再删边,直到求得最短路长度大于第一次求得的长度为止,不过用脚趾头想都知道数据肯定会卡你的。

其实会发现如果抛弃最短路来看,这道题很像最大流,就是所有边权为1求最大流的题目,不过现在加了约束条件必须在最短路上取最大流。所以我们可以求出所有的最短路径的边并重新建一个边权为1的图,在其上做最大流就可以了,那么怎么求所有最短路径呢?

有个方法是从终点dijkstra一下再从起点dijkstra下(注意要建立反向边图),假设dis1[u]表示start-u之间最短距离,dis2[v]表示v-end之间最短距离,那么只要dis1[u]+dis2[v]+dis[u][v] == 最短路长度,就代表这条边是可以要的

 #include <iostream>
#include <string.h>
#include <cstdio>
#include <queue>
#include <map>
#include <vector>
#include <string>
#include <cstring>
#include <algorithm>
#include <math.h> #define SIGMA_SIZE 26
#pragma warning ( disable : 4996 ) using namespace std;
typedef long long LL; inline LL LMax(LL a,LL b) { return a>b?a:b; }
inline LL LMin(LL a,LL b) { return a>b?b:a; }
inline int Max(int a,int b) { return a>b?a:b; }
inline int Min(int a,int b) { return a>b?b:a; }
inline int gcd( int a, int b ) { return b==?a:gcd(b,a%b); }
inline int lcm( int a, int b ) { return a/gcd(a,b)*b; } //a*b = gcd*lcm
const long long INF = 0x3f3f3f3f3f3f3f3f;
const int inf = 0x3f3f3f3f;
const int mod = ;
const int maxk = 1e5+;
const int maxn = ; int N, M, cnt;
int st, ed;
int num[maxk*];
int disst[maxn], dised[maxn], cur[maxn];
int linjie1[maxn], linjie2[maxn];
bool vis[maxn]; struct node {
int to, next, val;
}e1[maxk], e2[maxk]; void addedge1( int u, int v, int val )
{ e1[cnt].to = v; e1[cnt].val = val; e1[cnt].next = linjie1[u]; linjie1[u] = cnt++; }
void addedge2( int u, int v, int val )
{ e2[cnt].to = v; e2[cnt].val = val; e2[cnt].next = linjie2[u]; linjie2[u] = cnt++; } void init()
{
cnt = ;
memset( linjie1, -, sizeof(linjie1) );
memset( linjie2, -, sizeof(linjie2) );
} void dijkstra( int x )
{
memset( vis, , sizeof(vis) );
memset( disst, 0x3f, sizeof(disst) );
disst[x] = ; for ( int k = ; k <= N; k++ )
{
int mark = -, mindis = inf;
for ( int i = ; i <= N; i++ )
if ( !vis[i] && disst[i] < mindis )
{
mark = i;
mindis = disst[i];
}
vis[mark] = true; for ( int i = linjie1[mark]; i+; i = e1[i].next )
{
int v = e1[i].to, cost = e1[i].val;
if ( !vis[v] && disst[v] > disst[mark] + cost )
disst[v] = disst[mark] + cost;
}
}
} void make_map()
{
cnt = ;
int mindist = disst[ed]; for ( int i = ; i <= N; i++ )
for ( int j = linjie1[i]; j + ; j = e1[j].next )
{
int v = e1[j].to, cost = e1[j].val;
if ( disst[i] + cost + dised[v] == mindist )
addedge2( i, v, );
}
} int bfs()
{
memset( disst, -, sizeof(disst) );
queue<int> q; q.push(st);
disst[st] = ; while( !q.empty() )
{
int run = q.front(); q.pop();
for( int i = linjie2[run]; i+; i = e2[i].next )
{
int v = e2[i].to, flow = e2[i].val;
if( disst[v] < && flow > )
{
disst[v] = disst[run] + ;
q.push(v);
}
}
} if( disst[ed] > )
return ;
else
return ;
} int find( int s, int low )
{
int ff = ;
if( s == ed )
return low;
for( int& i = cur[s]; i+; i = e2[i].next ) //注意int& i = cur[s] 当前弧优化
{
int v = e2[i].to, cap = e2[i].val;
if( cap >
&& disst[v] == disst[s] +
&& (ff = find(v,Min(cap,low))) )
{
e2[i].val -= ff;
//e2[i^1].val += ff;
return ff;
}
}
return ;
} int dinic()
{
int ans = ;
int tans;
while( bfs() )
{
for( int i = ; i <= N; i++ ) //当前弧优化
cur[i] = linjie2[i];
while( tans = find( st, inf ) )
ans += tans;
}
return ans;
} int main()
{
int T; cin >> T;
while (T--)
{
scanf("%d%d", &N, &M); init();
for (int i = , j = ; i <= M; i++)
{
scanf( "%d%d%d", &num[j], &num[j+], &num[j+] );
addedge1(num[j+],num[j],num[j+]);
j += ;
} scanf("%d%d", &st, &ed); dijkstra(ed);
for ( int i = ; i <= N; i++ )
dised[i] = disst[i];
cnt = ;
memset( linjie1, -, sizeof(linjie1) );
for ( int i = , j = ; i <= M; i++ )
{
addedge1( num[j], num[j+], num[j+] );
j += ;
}
dijkstra(st);
make_map(); printf( "%d\n", dinic() );
}
return ;
}

kuangbin带我飞QAQ 最短路的更多相关文章

  1. kuangbin带我飞QAQ 线段树

    1. HDU1166 裸线段树点修改 #include <iostream> #include <string.h> #include <cstdio> #incl ...

  2. kuangbin带我飞QAQ 并查集

    1. POJ 2236 给出N个点,一开始图是空白的,两个操作,一个是增加一个点(给出坐标),一个是查询两个点间是否相通,当两点间的距离小于D或者两点通过其他点间接相连时说这两个点相通.并查集维护,每 ...

  3. kuangbin带我飞QAQ DLX之一脸懵逼

    1. hust 1017 DLX精确覆盖 模板题 勉强写了注释,但还是一脸懵逼,感觉插入方式明显有问题但又不知道哪里不对而且好像能得出正确结果真是奇了怪了 #include <iostream& ...

  4. kuangbin带你飞 最短路 题解

    求一个图最短路边的办法.好像下面的那个有问题.单向边和双向边一定是有区别的.这个比较容易.参照该文的最短路网络流题目和连通图题目一题求最短路关节边 另外上述2个题目的代码好像有问题. 在UVALIVE ...

  5. 最短路(代码来源于kuangbin和百度)

    最短路 最短路有多种算法,常见的有一下几种:Dijstra.Floyd.Bellman-Ford,其中Dijstra和Bellman-Ford还有优化:Dijstra可以用优先队列(或者堆)优化,Be ...

  6. cdoj 秋实大哥带我飞 最短路走法 含0权边

    //做完这题以后终于理解白书上的边为什么要那样定义了 可以很方便的在o(1) 时间内找到反向边 解法:先跑一边最短路,然后检查最短路上有没有0权边(dfs就好,但是每条边只能走一次,这里就需要用异或找 ...

  7. [kuangbin带你飞]专题四 最短路练习 POJ 3268 Silver Cow Party

    题意: 在一个有向图中求n头牛从自己的起点走到x再从x走回来的最远距离 思路一开始是暴力跑dij…… 讲道理不太可能…… 然后就百度了一下 才知道把矩阵转置的话就只需要求两次x的单源最短路…… /* ...

  8. [ An Ac a Day ^_^ ] [kuangbin带你飞]专题四 最短路练习 POJ 2387 Til the Cows Come Home

    求1到N的最短路 注意有重边 跑一遍dijkstra就行 /* *********************************************** Author :Sun Yuefeng ...

  9. 【算法系列学习】SPFA邻接表最短路 [kuangbin带你飞]专题四 最短路练习 F - Wormholes

    https://vjudge.net/contest/66569#problem/F 题意:判断图中是否存在负权回路 首先,介绍图的邻接表存储方式 数据结构:图的存储结构之邻接表 邻接表建图,类似于头 ...

随机推荐

  1. VMware Workstation 10 简体中文安装教程

    分享到 一键分享 QQ空间 新浪微博 百度云收藏 人人网 腾讯微博 百度相册 开心网 腾讯朋友 百度贴吧 豆瓣网 搜狐微博 百度新首页 QQ好友 和讯微博 更多... 百度分享 分享到 一键分享 QQ ...

  2. .net core模糊查询及分页

    在项目文件夹中,创建 PaginatedList类,然后用以下代码替换模板代码. using Microsoft.EntityFrameworkCore; using System; using Sy ...

  3. where与having区别

    解释一. 聚合函数是比较where.having 的关键. 开门见山.where.聚合函数.having 在from后面的执行顺序: where>聚合函数(sum,min,max,avg,cou ...

  4. mac brew nginx php php-fpm xdebug

    /usr/local/opt/nginx/bin/nginx -v brew services restart nginx sudo /usr/local/sbin/php-fpm --fpm-con ...

  5. webpack英文文档

    https://github.com/webpack/docs/wiki/contents

  6. 廖雪峰Java12maven基础-2maven进阶-1使用插件

    1.maven的Lifecycle,Phase和Goal: 使用maven构建项目就是执行Lifecycle 执行Lifecycle就是按顺序执行一系列Phase 每执行一个Phase,都会执行该Ph ...

  7. 流程控制&&函数

    1.if 条件语句 if 判断条件: 执行语句…… elif 判断条件: 执行语句…… else: 执行语句…… 2.for 循环 ''' for 后跟变量名,in 后跟序列,注意加冒号 for 循环 ...

  8. 正则获取html标签字符串中图片地址

    html标签字符串: var htmlStr = "<div class='testClass'><img=http://www.chinanews.com/part/ho ...

  9. (转)剖析Linux文件编码的查看及修改

    Linux文件编码的查看和修改都有不止一种做法,如果你需要在Linux中操作windows下的文件,那么很可能会经常遇到文件编码转换的问题,如何进行这项工作,也应该是经常工作在双系统下的操作者的必须掌 ...

  10. 深入浅出 Java Concurrency (34): 线程池 part 7 线程池的实现及原理 (2)[转]

    线程池任务执行流程 我们从一个API开始接触Executor是如何处理任务队列的. java.util.concurrent.Executor.execute(Runnable) Executes t ...