输入说明
第一行 点数n 边数m 集合中字符数目k
第二行 集合中的字符
接下去m行 每一行三个值 起点 终点 经过的边上的字符
输出:
构造好的边
新构造节点包含的原先的点的集合
#include <iostream> #include <cstdio> #include <cmath> #include <algorithm> #include <cstring> #include <stack> #include <queue> #include <string> #include <vector> #include <set> #include <map> #define pb push_back #define mp make_pair #define all(x) (x).begin(),(x).end() #define sz(x) ((int)(x).size()) #define fi first #define se second using namespace std; typedef vector<int> vi; const int N = 1000; int n,m,k; struct Edge{ int to,nxt; char w; }; class Graph{ private: int *head; int tot; Edge *edge; vector<vi> ans; bool *vis; queue<vi> que; vector<char> chArray; int n,m; public : void init(int _n,int _m){ n=_n;m=_m; cout<<n<<" "<<m<<endl; head=(int*)malloc(sizeof(int)*(n)); for(int i=0;i<n;i++) head[i]=-1; edge=(Edge*)malloc(sizeof (Edge)*(m*2)); vis=(bool*)malloc(sizeof(bool)*n); tot=0; chArray.clear(); ans.clear(); } void addEdge(int u,int v,char w){ edge[tot].w=w; edge[tot].to=v; edge[tot].nxt=head[u]; head[u]=tot++; } void addCh(char ch){ chArray.pb(ch); } bool _same(vi a,vi b){ if(a.size()!=b.size()) return false; sort(all(a)); sort(all(b)); for(int i=0;i<a.size();i++) if(a[i]!=b[i]) return false; return true; } int find_pos(vi a){ for(int i=0;i<ans.size();i++) if(_same(ans[i],a)) return i; return ans.size(); } void print_vi(vi v){ for(int i=0;i<v.size();i++) cout<<v[i]<<" "; cout<<endl; } void subset_construction(int start,int en){ while(que.size()) que.pop(); vi _tmp; _tmp.pb(start); vi tmp=find_ch_path(_tmp,'e'); que.push(tmp); ans.pb(tmp); while(!que.empty()){ vi now=que.front(); que.pop(); for(int i=0;i<chArray.size();i++){ int w=chArray[i]; vi tmp=find_ch_path(now,w); tmp=find_ch_path(tmp,'e'); int pos=find_pos(tmp); if(pos>=ans.size()) { ans.pb(tmp); que.push(tmp); } int from=find_pos(now); if(from!=pos) cout<<from<<" "<<pos<<" "<<(char)w<<endl; } } } void print(){ cout<<"the whole num: "<<ans.size()<<endl; for(int i=0;i<ans.size();i++){ cout<<i<<": "; sort(all(ans[i])); for(int j=0;j<ans[i].size();j++) cout<<ans[i][j]<<" "; cout<<endl; } } vi find_ch_path(vi&in,char w){ for(int i=0;i<n;i++) vis[i]=false; vi ret; ret.clear(); for(int i=0;i<in.size();i++) { ret.pb(in[i]); vis[in[i]]=true; } for(int i=0;i<in.size();i++) { dfs(in[i],ret,w); } return ret; } void dfs(int u,vi& ret,char ch){ for(int k=head[u];~k;k=edge[k].nxt){ int v=edge[k].to; char w=edge[k].w; if(vis[v] || w!=ch) continue; vis[v]=true; ret.pb(v); dfs(v,ret,ch); } } }G; int main() { freopen("aaa","r",stdin); cin>>n>>m>>k; G.init(n,m); for(int i=0;i<k;i++){ char ch; cin>>ch; G.addCh(ch); } for(int i=1;i<=m;i++){ int u,v;char ch; cin>>u>>v>>ch; G.addEdge(u,v,ch); } G.subset_construction(0,n-1); G.print(); return 0; }
15 18 2
a b
0 1 e
1 2 e
1 4 e
2 3 a
4 5 b
3 6 e
5 6 e
6 7 e
6 1 e
0 7 e
7 8 a
8 9 e
8 11 e
9 10 a
11 12 b
10 13 e
12 13 e
13 14 e