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. 批量更新mysql表数据

    1.批量更新表中某个字段,如果表比较大,每条记录都执行一条update,1s执行10条数据,10万条数据就要1W秒,3个多小时. 2.可以用case when 来实现,模板如下 UPDATE cate ...

  2. Django2.0+小程序技术打造微信小程序助手✍✍✍

    Django2.0+小程序技术打造微信小程序助手  整个课程都看完了,这个课程的分享可以往下看,下面有链接,之前做java开发也做了一些年头,也分享下自己看这个视频的感受,单论单个知识点课程本身没问题 ...

  3. shell脚本练习06

    ######################################################################### # File Name: -.sh # Author ...

  4. php非法输入数据类型

    1.空白输入 2.超长输入(如大于256个字符) 3.特殊字符(如·!@#¥%……&*()—=|.:‘:<>;'"<>?.,) 4.控制字符(如\r\n等) ...

  5. Java 怎样实现调用其他方法

    Java主类的main方法调用其他方法 方法1: funA()方法设为静态方法. 当主类加载到内存,funA()分配了入口地址,主要代码如下: public class test{ static vo ...

  6. mysql权限操作

    1.mysql权限操作 grant select,insert on test1.tb1 to ltx2@127.0.0.1 默认权限:什么都没有 2.用户管理特殊命令: 创建用户:create us ...

  7. IDEA Error:java: Compilation failed: internal java compiler error 解决方案

    这是由于版本不一致导致的 file => settings => 搜索找到Java Compiler 把相应jdk版本改成1.8 ctrl+alt+s

  8. BZOJ 1579 [Usaco2009 Feb]Revamping Trails 道路升级

    堆优化的dijkstra. 把一个点拆成k个. 日常空间要开炸一次.. //Twenty #include<cstdio> #include<cstring> #include ...

  9. wget: command not found 解决方案

    wget: command not found 解决方案 wget command not found 解决方案 问题分析 解决方案 方法一yum安装wget 方法二rpm安装 问题分析 安装的是Ce ...

  10. spring容器创建bean对象的方式

    xml文件中有bean的配置,而且这个bean所对应的java类中存在一个无参构造器 那么这个时候spring容器就可以使用反射调用无参构造器来创建实例了(常规的方式) 通过工厂类获得实例(工厂类实现 ...