标签:队列 存在 int sort lag spfa imp typedef sync
D.UVa12880
解题关键:dfs,判断每个人是否愿意被其他人交换,注意保证每个人只能被交换一次。
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 #include<cstdlib> 5 #include<cmath> 6 #include<iostream> 7 #define maxn 220000 8 using namespace std; 9 typedef long long ll; 10 struct Edge{ 11 int nxt; 12 int to; 13 }e[maxn]; 14 int head[maxn],cnt,pre[maxn]; 15 bool vis[maxn]; 16 void add_edge(int u,int v){//单向 17 e[cnt].to=v; 18 e[cnt].nxt=head[u]; 19 head[u]=cnt++; 20 } 21 bool dfs(int u){ 22 for(int i=head[u];i!=-1;i=e[i].nxt){ 23 int v=e[i].to; 24 if(vis[v]) continue; 25 vis[v]=true; 26 if(pre[v]==-1||dfs(pre[v])){ 27 pre[v]=u; 28 return true; 29 } 30 } 31 return false; 32 } 33 int main(){ 34 int n,m,a,b; 35 while(scanf("%d%d",&n,&m)!=EOF){ 36 memset(head, -1, sizeof head); 37 memset(pre,-1,sizeof pre); 38 cnt=0; 39 for(int i=0;i<m;i++){ 40 scanf("%d%d",&a,&b); 41 add_edge(a,b); 42 } 43 for(int i=0;i<n;i++){ 44 memset(vis,0,sizeof vis); 45 dfs(i); 46 } 47 bool flag=false; 48 for(int i=0;i<n;i++){ 49 if(pre[i]==-1){ 50 flag=true; 51 break; 52 } 53 } 54 if(flag) printf("NO\n"); 55 else printf("YES\n"); 56 } 57 return 0; 58 }
E.hdu4313
解题关键:正向的思路是将边从小到大排序,如果去掉某条边,两个特殊点并起来了,则需去掉该边,我们反向考虑,将边从大到小排序,依次向图中加边,如果两个点并起来了,则需去掉该边。
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 #include<cstdlib> 5 #include<iostream> 6 #include<vector> 7 #include<cmath> 8 #define maxn 100020 9 using namespace std; 10 typedef long long ll; 11 int par[maxn],n,k; 12 //bool vis[maxn]; 13 struct edge{ 14 int u; 15 int v; 16 int w; 17 }e[maxn]; 18 bool flag[maxn]; 19 bool cmp(const edge &a,const edge &b){ 20 return a.w>b.w; 21 } 22 void init1(){ 23 for(int i=0;i<=n;i++) par[i]=i; 24 } 25 26 int find1(int x){ 27 if(par[x]==x) return x; 28 else return par[x]=find1(par[x]); 29 } 30 31 void unite(int x,int y){ 32 par[x]=y; 33 } 34 35 int main(){ 36 int t,a; 37 ios::sync_with_stdio(0); 38 cin>>t; 39 while(t--){ 40 memset(flag, 0, sizeof flag); 41 cin>>n>>k; 42 init1(); 43 for(int i=0;i<n-1;i++){ 44 cin>>e[i].u>>e[i].v>>e[i].w; 45 } 46 sort(e,e+n-1,cmp); 47 for(int i=0;i<k;i++){ 48 cin>>a; 49 flag[a]=1; 50 } 51 ll ans=0; 52 for(int i=0;i<n-1;i++){ 53 if(flag[find1(e[i].u)]&&flag[find1(e[i].v)]){ 54 ans+=e[i].w; 55 } 56 else if(flag[find1(e[i].u)]){ 57 unite(find1(e[i].v),find1(e[i].u)); 58 }else{ 59 unite(find1(e[i].u), find1(e[i].v)); 60 } 61 } 62 cout<<ans<<"\n"; 63 } 64 return 0; 65 }
G.hdu4318
解题关键:最短路转化为最长路。
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 #include<cstdlib> 5 #include<iostream> 6 #include<cmath> 7 #include<queue> 8 using namespace std; 9 const int maxn=50002; 10 const int maxm=2600010; 11 int head[maxn],tot,n,m; 12 struct edge{ 13 int to; 14 double w; 15 int nxt; 16 }e[maxm]; 17 void add_edge(int u,int v,double w){ 18 e[tot].w=w; 19 e[tot].to=v; 20 e[tot].nxt=head[u]; 21 head[u]=tot++; 22 } 23 bool vis[maxn]; 24 queue<int>que;//队列是点的队列 25 double d[maxn]; 26 void spfa(int s){ 27 for(int i=0;i<=n;i++) d[i]=0.0; 28 memset(vis,0,sizeof vis); 29 while (!que.empty()) que.pop(); 30 que.push(s); 31 vis[s]=true; 32 d[s]=1.0; 33 while (!que.empty()){ 34 int u=que.front(); 35 que.pop(); 36 vis[u]=false; 37 for (int i=head[u];i!=-1;i=e[i].nxt){ 38 int v=e[i].to; 39 double w=e[i].w; 40 if (d[v]<d[u]*w){ 41 d[v]=d[u]*w; 42 if (!vis[v]){ 43 vis[v]=true; 44 que.push(v);//hash一下,可判断是否存在负环 45 } 46 } 47 } 48 } 49 } 50 int main(){ 51 int a,b,k,td; 52 //double c; 53 while(scanf("%d",&n)!=EOF){ 54 memset(head, -1, sizeof head); 55 tot=0; 56 for(int i=0;i<n;i++){ 57 scanf("%d",&k); 58 for(int j=0;j<k;j++){ 59 scanf("%d%d",&b,&td); 60 add_edge(i+1,b,1-td*0.01); 61 } 62 } 63 scanf("%d%d%d",&a,&b,&td); 64 spfa(a); 65 if(d[b]==0){ 66 printf("IMPOSSIBLE!\n"); 67 }else{ 68 printf("%.2f\n",td-td*d[b]); 69 } 70 } 71 return 0; 72 }
标签:队列 存在 int sort lag spfa imp typedef sync
原文地址:http://www.cnblogs.com/elpsycongroo/p/7648697.html